{"id":52,"date":"2017-09-27T20:09:49","date_gmt":"2017-09-27T19:09:49","guid":{"rendered":"http:\/\/www.hoagieshouse.com\/blog\/?p=52"},"modified":"2017-09-19T20:10:10","modified_gmt":"2017-09-19T19:10:10","slug":"really-simple-raspberry-pi-logic-analyser-digital-oscilloscope","status":"publish","type":"post","link":"http:\/\/www.hoagieshouse.com\/blog\/pi\/really-simple-raspberry-pi-logic-analyser-digital-oscilloscope\/","title":{"rendered":"Really Simple Raspberry Pi Logic Analyser (Digital Oscilloscope)"},"content":{"rendered":"<p>The source here is an extremely simple 2 channel Logic Analyser. It shows two digital signals like an oscilloscope would, but its extremely simple and easily extendable.<\/p>\n<p><!--more--><\/p>\n<p>For the ultrasonic distance sensor, I wanted to check my code an wiring was doing what I thought. Ideally, I would have connected up an oscilloscope and looked at the signals that way, but my &#8216;scope is ancient and hasn&#8217;t been used for so long I don&#8217;t exactly know where it is anymore. But I&#8217;m working with a Pi and there&#8217;s plenty of IO available and a couple of CPU cores I&#8217;m not really using either so why not make one.<\/p>\n<p>The code below defines 2 pins to collect data on. These are in the wiringPi pin numbering scheme. My other code is also using these pins and has already set up the direction an pull-ups as required so I had the pinMode lines\u00a0 commented out when I used it.<\/p>\n<p>The basic operation is to wait until the input of channel 1 is low, then goes high. Then it takes 101 samples from the two pins with a small delay between each one. Finally it plots the traces. I use . and # for my traces as it&#8217;s nice and clear what&#8217;s high and low. I could have messed about with the line drawing characters, but keeping it simple was the priority.<\/p>\n<pre>\/\/ g++ -o dso dso.cpp -lwiringPi\r\n\r\n\/\/ #includes for various stuff\r\n#include \r\n#include \r\n#include \r\n\r\n\/\/ Parameters for the main code\r\n#define LEN 101\r\n#define INPIN1 4\r\n#define INPIN2 5\r\n\r\nint main (void)\r\n{\r\n  if (wiringPiSetup () == -1)\r\n    return 1;\r\n\r\n  pinMode (INPIN1, INPUT);\r\n  pinMode (INPIN2, INPUT);\r\n\r\n  \/\/ Optionally turn off the pullup\/down resustors.\r\n  \/\/pullUpDnControl (INPIN1, PUD_OFF);\r\n  \/\/pullUpDnControl (INPIN2, PUD_OFF);\r\n\r\n  bool ch1[LEN];\r\n  bool ch2[LEN];\r\n\r\n  while (true)\r\n  {\r\n    \/\/ Wait for trigger\r\n    while (digitalRead(INPIN1));\r\n    while (!digitalRead(INPIN1));\r\n\r\n    \/\/ Sample the data\r\n    for(int i = 0 ; i &lt; LEN ; i++)\r\n    {\r\n      ch1[i] = digitalRead(INPIN1);\r\n      ch2[i] = digitalRead(INPIN2);\r\n      usleep(1);\r\n    }\r\n\r\n    \/\/ Display the data\r\n    printf(\"\\n\\n\\n\\n\");\r\n    printf(\"\\n.         .         .         .         .         .         .         .         .         .         .\\n\");\r\n    for(int i = 0 ; i &lt; LEN ; i++)\r\n    {\r\n      printf(ch1[i]? \"#\" : \".\");\r\n    }\r\n\r\n    printf(\"\\n.         .         .         .         .         .         .         .         .         .         .\\n\");\r\n    for(int i = 0 ; i &lt; LEN ; i++)\r\n    {\r\n      printf(ch2[i]? \"#\" : \".\");\r\n    }\r\n    printf(\"\\n.         .         .         .         .         .         .         .         .         .         .\\n\");\r\n  }\r\n\r\n  \/\/ Pointless return as we never get here, but it keeps the compiler happy.\r\n  return 0;\r\n}\r\n<\/pre>\n<p>I usually put the command line to build simple apps like this at the top of the source file, as you can see this one is built with<\/p>\n<pre>g++ -o dso dso.cpp -lwiringPi\r\n<\/pre>\n<p>It requires g++ and the wiringPi library to build. They can both be obtained with apt-get on the Raspbian OS.<\/p>\n<p>In case you&#8217;re wondering why I take 101 samples instead of 100, it just looks better with the 10 sample grid lines.<\/p>\n<p>As the Pi Operating System supports multi tasking, there&#8217;s a possibility that this will be interrupted while sampling the data. This doesn&#8217;t seem to be a problem whenever I&#8217;ve tried it, but if you use this and occasionally see the chunks of time missing from your traces, that&#8217;s probably why. You could run this in high priority to avoid that, but I&#8217;ve never found the need to. I am using a Pi version 3 though which has a 4 core CPU so is more able to leave my process alone.<\/p>\n<h2>Improvements<\/h2>\n<p>The timing is handled by usleep. It seems fine, but doesn&#8217;t account for the time taken to actually sample the data and loop the counter etc. I&#8217;m sure there are better methods.<br \/>\nThe trace is shown as hashes and dots. I find it nice and easy to read like that, but some people would doubtless prefer proper lines. There should be some extended characters to draw these.<br \/>\nControls of any kind that don&#8217;t mean re-compiling the source would definitely be an improvement. As would some kind of timing information. At them moment you just have to know it&#8217;s 1uS per character and therefore 10uS per grid line.<br \/>\nAnalogue input, and of course display, would be nice too. To do that you&#8217;d need to use an analogue capture system of some kind and a graphical interface.<br \/>\nThe list goes on, but my primary focus was to get two traces on my screen as quickly and simply as possible.<\/p>\n<p>If ever I do introduce any of these improvements, I&#8217;ll add a blog entry about it. Watch this space, but don&#8217;t hold your breath.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The source here is an extremely simple 2 channel Logic Analyser. It shows two digital signals like an oscilloscope would, but its extremely simple and easily extendable.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[3,6],"tags":[],"_links":{"self":[{"href":"http:\/\/www.hoagieshouse.com\/blog\/wp-json\/wp\/v2\/posts\/52"}],"collection":[{"href":"http:\/\/www.hoagieshouse.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.hoagieshouse.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.hoagieshouse.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.hoagieshouse.com\/blog\/wp-json\/wp\/v2\/comments?post=52"}],"version-history":[{"count":4,"href":"http:\/\/www.hoagieshouse.com\/blog\/wp-json\/wp\/v2\/posts\/52\/revisions"}],"predecessor-version":[{"id":56,"href":"http:\/\/www.hoagieshouse.com\/blog\/wp-json\/wp\/v2\/posts\/52\/revisions\/56"}],"wp:attachment":[{"href":"http:\/\/www.hoagieshouse.com\/blog\/wp-json\/wp\/v2\/media?parent=52"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.hoagieshouse.com\/blog\/wp-json\/wp\/v2\/categories?post=52"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.hoagieshouse.com\/blog\/wp-json\/wp\/v2\/tags?post=52"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}