Go Down

Topic: Arduino Single Channel Logic Analyser (Read 4162 times) previous topic - next topic

Riva

Mar 24, 2013, 07:10 pm Last Edit: Mar 25, 2013, 11:09 am by Riva Reason: 1
I have this idea that an arduino could be used as a simple logic analyser. People without such toys asking on here for help decoding  IR remote, Serial or RF transmitter data could be asked to load a sketch, attach the device and grab some data that can be used to decode/debug.
As the arduino has very little memory I figure the best way to sample data is to grab pin transition times instead of taking a sample every x micro seconds. Store the time in a circular buffer so you can start serial printing the data out ASAP while still capturing, to further extend the capture duration.
I have started on some arduino code and it seems to be working okay (still debugging it) but now the data needs displaying on the computer and this is where I'm hoping someone else will be willing/able to help.
I figure the best option to make the PC code is to use something like Processing as it's free and works on Windows, Linux & Mac.
Does anyone think this is a good idea and is willing to write/help write the processing code to realize the idea.

Attached is an idea of what the Processing output should look like though it would be single channel only. It would need ability to zoom in/out and maybe measure time between 2x user movable cursors.
Also attached is a sample dump of the serial data from this capture session. Each number is the approx duration in milliseconds since the last transition and bit zero of this number denotes if the signal is high/low (1=high, 0=low)

This is unpaid as I want the code to become public domain.

EDIT: Added current Arduino code


Coding Badly

captureMode has to be protected by a critical section in loop.

bufferWrite probably has to be protected by a critical section.

bufferRead probably has to be protected by a critical section.

This...
Code: [Select]
    if (noiseThreshold > 0){
      if (microDiff < noiseThreshold){                      // Pulse to short?
        return;                                             // Yes, so drop out now
      }
    }

...may be useless and could cause problems.  I believe the hardware that detects CHANGE already has noise suppression.

Code: [Select]
        //noInterrupts();
        noiseThreshold = (unsigned long)cmdData;
        //interrupts();

...any particular reason you comment-out those two important lines of code?

Code: [Select]
  Serial.begin(57600);                                      // Fast(ish) Serial
...250000, 500000, and 1000000 are better choices for the baud rate.


Overall I like it.  Karma for you.

Riva

#2
Mar 26, 2013, 10:08 am Last Edit: Mar 26, 2013, 06:29 pm by Riva Reason: 1

captureMode has to be protected by a critical section in loop.
I've hopefully protected captureMode where it counts now. I figure there is less need to protect when capture not active as ISR does not access anything but captureMode and it's byte size so will never get interrupted half way though storing a byte (I hope).
bufferWrite probably has to be protected by a critical section.
bufferRead probably has to be protected by a critical section.
Done.
This...
Code: [Select]
   if (noiseThreshold > 0){
     if (microDiff < noiseThreshold){                      // Pulse to short?
       return;                                             // Yes, so drop out now
     }
   }

...may be useless and could cause problems.  I believe the hardware that detects CHANGE already has noise suppression.
Believe it or not I get lots of little spikes without it set to something like 50 (default) but the main reason for having this is so reading a device like an analogue RF receiver that could exhibit noise when not receiving a signal I can suppress false readings by adjusting it.

Code: [Select]
       //noInterrupts();
       noiseThreshold = (unsigned long)cmdData;
       //interrupts();

...any particular reason you comment-out those two important lines of code?
In debugging I must have commented them out but forgot to put them back in, thanks.

Code: [Select]
 Serial.begin(57600);                                      // Fast(ish) Serial
...250000, 500000, and 1000000 are better choices for the baud rate.
Now 115200

I currently use freeMemory to show how much RAM is spare so I can eventually tweak the buffer size but I really need to know if things like the stack are dynamic and can grow into the free memory or does it have a fixed space not included in the freeMemory result. This is so if I increase ringBuffer so only 20 or so bytes remain will the stack or Serial grow into this space and corrupt?

EDIT: Added sketch

Coding Badly

I've hopefully protected captureMode where it counts now. I figure there is less need to protect when capture not active as ISR does not access anything but captureMode and it's byte size so will never get interrupted half way though storing a byte (I hope).


The problem is that you manipulate individual bits.  captureMode has to be fetched, altered, and then stored when you change a bit.  The risk is that an interrupt occurs after fetch but before store.  At that point the value stored may have been poisoned.

Graynomad

For your PC client have a look at SUMP

http://www.sump.org/projects/analyzer/client/

I think it will do what you want, all you have to do is spit out the data in the right format.

______
Rob
Rob Gray aka the GRAYnomad www.robgray.com

Riva


The problem is that you manipulate individual bits.  captureMode has to be fetched, altered, and then stored when you change a bit.  The risk is that an interrupt occurs after fetch but before store.  At that point the value stored may have been poisoned.

I think the only unprotected code now is when the capture is turned off so the ISR is only reading captureMode and not altering it.

Riva


For your PC client have a look at SUMP
I think it will do what you want, all you have to do is spit out the data in the right format.

I have seen SUMP but not keen to run it as it need Java console.

Riva

Disappointingly not much takeup on this project so I have posted my current work in progress of the arduino and processing code. I'm no C++ programmer and until I started this thread had never seen processing so the code I a bit of a Frankenstein's monster.
Basically load the arduino sketch on the arduino and the processing sketch into processing. In processing, toggle the trigger direction with the green box/button. Arm the capture using the red record circle/button & stop capturing with the blue square/button. The left/right cursors keys move along the capture data and the up/down adjust the scale. Enter key resets back to start of capture data and sets scale to 1.

Graynomad

#8
Apr 01, 2013, 06:15 pm Last Edit: Apr 01, 2013, 06:25 pm by Graynomad Reason: 1
I can't test this because I don't have processing installed. Anyway I have a real LA so don't really have the need.

Can you show a screen shot?

Also, what sort of samples rates are you getting?

_____
Rob
Rob Gray aka the GRAYnomad www.robgray.com

Riva


I can't test this because I don't have processing installed. Anyway I have a real LA so don't really have the need.
Processing is very like Arduino IDE. Just unpack to directory and run, no install needed.
I also have LA but though something like this would be useful to those without.

Can you show a screen shot?
Attached.
Also, what sort of samples rates are you getting?
The thing is driven by event (pin change interrupt) instead of the usual time slice method and seems happy down to about 50uS or above though this would obviously fill buffer a lot quicker with lots of quick switching. 

Graynomad

That looks pretty good actually. I've been saying for ages that if everyone had an LA we would only have half the questions on this forum, and even though you can buy a good one for $150 that's still too much for many people.

Quote
down to about 50uS

You could probably get faster, that code looks like it could be optimised a fair bit.

I think for this to be useful it has to be able to capture the 3 basic serial comms, UART, I2C and SPI as that's where a lot of people have trouble, they may have to be slowed down to do the capture but at least a user will see that the right information is being transmitted/received. If the app still doesn't work at the faster speed then that's a different problem but you know the fundamentals are in place.

Any chance of 2 channels? :)

______
Rob

Rob Gray aka the GRAYnomad www.robgray.com

Riva


That looks pretty good actually. I've been saying for ages that if everyone had an LA we would only have half the questions on this forum, and even though you can buy a good one for $150 that's still too much for many people.
My sentiments exactly, hence this project.

Quote
down to about 50uS

You could probably get faster, that code looks like it could be optimised a fair bit.
It will respond to shorter durations but in testing I found I had noise causing spurious triggers.

I think for this to be useful it has to be able to capture the 3 basic serial comms, UART, I2C and SPI as that's where a lot of people have trouble, they may have to be slowed down to do the capture but at least a user will see that the right information is being transmitted/received. If the app still doesn't work at the faster speed then that's a different problem but you know the fundamentals are in place.
I was mostly thinking of IR/RF signals you get from remote controls or weather station sensors but anything extra like you suggest would be useful. When I'm off shift I may get time to do more testing and will post results.

Any chance of 2 channels? :)
It should be possible to use the other interrupt pin to give a second channel and I did think about maybe doing a standard time slice version that logs 4 or 8 channels (though this has already been done with SUMP) but that's a future version assuming I get this polished and off the ground.

______
Rob



Riva

Okay, so I have done some tests and the results look reasonable though could be better.

Serial 9600 & Manchester
First image (black background) is from the signal generator, second image (grey background) is the capture using arduino.

Riva

1-Wire & I2C
First image (black background) is from the signal generator, second image (grey background) is the capture using arduino.

Riva

#14
Apr 03, 2013, 12:26 pm Last Edit: Apr 04, 2013, 01:09 pm by Riva Reason: 1
Finally SPI clock & IR remote
First image (black background) is from the signal generator, second image (grey background) is the capture using arduino. The IR only has arduino image.

Go Up