Step 25: Done! (Almost)

At the end of this long experience, I feel very satisfied because
  • I learned a lot about microcontrollers in general;
  • I learned a lot more about the Arduino ATMega328P;
  • I had some hands-on experience of Data Acquisition, not by using something already done but by making something;
  • I realized an amateur oscilloscope that is not that bad.
I hope that this guide will be useful to anybody that reads it. I wanted to write it so detailed because I learned all that in the hard way (surfing the internet, reading the datasheet and by a lot of trial and error) and I would like to spare anybody from that experience.
It is an awesome project.<br>Iam working on similar kind of projects,actually i am not that much good in Analog Electronics. I have some doubts,please help me<br>1) what is triggering?<br>2)why do we need to to give threshold voltage?arduino itself does the conversion right? Just like AnalogRead.<br>
<p>An oscilloscope lets you view a voltage in a small snapshot of time, but we need something to mark the start of that snapshot. Usually we wait for the voltage to hit a certain &quot;trigger&quot; point and that marks the beginning of the recording. Oscilloscopes usually take a snapshots continually. If we don't trigger at the same voltage each time, periodic (repeating) signals will not be displayed with any stability - every frame will show the signal in a different position for a split second and it becomes impossible to study the signal.</p>
Two ideas to make the code more efficient (run faster):<br><br>The calculation<br><br>ADCCounter = ( ADCCounter + 1 ) % ADCBUFFERSIZE;<br><br>involves an integer division which tends to be time consuming (at least on a Microchip PIC - I do not know Atmel as well). Instead, try<br><br>if (++ADCCounter &gt;= ADCBUFFERSIZE) ADCCounter = 0;<br><br>Second, you can completely avoid the time required to evaluate<br><br>if(wait) <br><br>and live without the wait variable if you simply set stopIndex to a value that the counter never reaches, as long as you aren't yet in the post-trigger phase. I.e. during initialization (when starting a new sweep) set<br><br>stopIndex = ADCBUFFERSIZE + 1;<br><br>and when the trigger event happens then just do as you did so far, but without the boolean wait variable:<br><br>ISR(ANALOG_COMP_vect)<br>{<br> // Disable Analog Comparator interrupt<br> cbi( ACSR,ACIE );<br><br> // Turn on errorPin<br> //digitalWrite( errorPin, HIGH );<br> sbi( PORTB, PORTB5 );<br><br> stopIndex = ( ADCCounter + waitDuration ) % ADCBUFFERSIZE;<br>}<br><br>and the ADC ISR routine becomes<br><br>ISR(ADC_vect)<br>{<br> if (++ADCCounter &gt;= ADCBUFFERSIZE) ADCCounter = 0;<br><br> if ( stopIndex == ADCCounter )<br> {<br> cbi( ADCSRA, ADEN );<br> freeze = true;<br> }<br>}<br>
<p>Hi there! Do I need to erase the line ADCBuffer[ADCCounter] = ADCH</p><p>before </p><p>if (++ADCCounter &gt;= ADCBUFFERSIZE) ADCCounter = 0;</p><p>in the ADC ISR routine?</p><p>Also, where do I have to put the line &quot;stopIndex = ADCBUFFERSIZE + 1;&quot;?</p><p>Thank you very much! Sorry my english!</p>
<p>Hi</p><p>you put stopIndex = ADCBUFFERSIZE + 1 at:</p><p>Girino.ino to replace the line:</p><p>&quot;wait = false;&quot;</p>
<p>I wish I had read this before I did my project. I could only get it to work with a prescaler as low as 4. I wanted to do 2, but it wouldn't respond.</p><p>After I had already torn out my test setup and put my project into production, I thought that maybe the ISR was taking too long. I looked at the assembly it created, and I came to the same conclusion that you did, that the integer division was part of the culprit. My solution would have been to set ADCBUFFERSIZE to 1024, which the compiler converted to a simple AND instruction. But I like your solution better. Isn't it funny how we sometimes write code that looks more elegant in C, but using a simple if block (that takes more code in C) actually builds more efficient machine code?</p>
Thank you very much womai for your precious advices! <br>This period is very though for me but I am planning to modify the project according to your suggestions.
<p>Finally, someone that realises the importance of detail. Many thanks for the time and effort you've put into this. This should be used as a benchmark for posting a project here.</p><p>Do you really need that last emitter follower though?</p>
<p>All I want is a bill of materials :(</p>
<p>Great Instructable</p>
<p>Can anyone help me, what pins of the arduino need to be connected where? I don't understand</p>
<p>Excellent article. However, you should also mention the higher ADC clock setting for lower resolution than 8 bits.</p><p>Also, the link no longer works.</p><p><a href="http://www.phy.uct.ac.za/courses/python/examples/moreexamples.html#oscilloscope-and-spectrum-analyser" rel="nofollow">http://www.phy.uct.ac.za/courses/python/examples/moreexamples.html#oscilloscope-and-spectrum-analyser</a></p>
<p>I am finding difficulty to understand pin connections to the Arduino from LM324..please help me</p>
<p>Hi, I've added your project to the <em style="">&quot;</em><em style="">Make Your Own Oscilloscope!</em><em style="">&quot;</em> Collection</p><p>This is the link If you are interested:</p><p><a href="https://www.instructables.com/id/Make-Your-Own-Oscilloscope/">https://www.instructables.com/id/Make-Your-Own-Osci...</a></p>
<p>I don't see where you mention what sample rates you were getting with this. I was in a desperate situation last week where I needed an oscilloscope to check on an automotive signal, I didnt know if it was 5V or 12V or the wave shape. I built one in an hour (a few 100K pots as voltage dividers from 16V to 5V), and a small sketch... Sampling 4 ADC channels I was getting 400 samples/second at 10 bit resolution, I transferred each sample in a 2 bytes over serial.</p><p>Starting with the high bit of the high byte</p><p>H7 = Text identifier (1=Data, 0 is debug, since you usually only print &lt;128 ascii value characters in debug</p><p>H6= High byte ID (Always 1)</p><p>H5 = Address bit 1</p><p>H4 = Address bit 2</p><p>H3 -&gt; H0 = Data bit 9 -&gt; 6 respectively</p><p>Now the low byte</p><p>L7 = Text identifier (same as high byte)</p><p>L6 = Low byte ID (Always 0)</p><p>L5 -&gt;L0 = Data bit 5 -&gt;0 respectively</p><p>This enabled me to transfer my data, even if it got corrupted and have error recovery using only 2 bytes per sample, and doing only bitwise operations, leaving all the scaling, etc to be done by the computer.. I made a small VB program that parsed the serial input. It also made it possible to print raw ADC values directly to the serial port in human readable form while keeping the data flowing to the program.</p><p>The VB 'frontend' just outputted the values to a CSV file with a timestamp (not perfectly accurate) that I opened in excel, where I could graph it from there. not the prettiest way of doing it but it worked for what I needed</p>
<p>Doh, I see the sample rate now.. so never mind that part</p>
<p>Caffeinomane congrats, it looks like 3 years are passed and it's still one of the best project online for cheap oscilloscope! </p><p>It surprise me that I could't find any android gui (via bluetooth, I'd expect). Anyone is aware of it? </p><p>If not I'm gonna work on a simple interface. I'll make it opensource of course. Anyone would show some interested? let me hear some feedback!</p><p>Thank you, and kind regards!</p>
<p>interested in hooking it up to a web server on a raspberry pie to display charts on my phones web browser</p>
<p>grate idea keep doing!</p>
<p>Hi All! There is a nice project of an Oscilloscope with Arduino UNO and miuPanel that permits to see and control the oscilloscope with a smart phone. The sample rate is 50 kSa/s, it implements the trigger and can provide more than 20 FPS on a smartphone LCD. See: http://www.miupanel.com/Projects/Arduino-Advanced-Oscilloscope You could use miuPanel too to provide the graphical interface to your Arduino projects.</p>
<p>Nice project, I wrote a GUI in c++ and did some work on firmware and PCB. Available <a href="https://hackaday.io/project/5881-small-scope" rel="nofollow">here</a>. </p>
<p>Great project!</p><p>Congratulations and keep going!</p>
<p>That's a really nice tutorial, very clear in every step.</p><p>Still, it misses something very basic : a summary of the used pins on the arduino and the functions that goes with them. It's annoying that we have to dive in the code to search for the input pin used by default. </p>
<p>i know this sounds really stupid but i somehow can't see how to actually see the signal ?? which pins in the uno should i connect the input signal to ?</p>
<p>I have a question about the low-pass filter. Using a 1.8k resistor and a 1uF capacitor gets you a cut-off frequency of 88.5Hz [ 1/(2*pi*R*C) ], not 560Hz [ 1 / (R*C) ] which is rad/s.</p><p>Question is, should correct the filter to cut-off at 560Hz or is it okay as it is to cu-off at 88Hz=560 rad/s?</p>
<p>Did anyone else have problems compiling?</p><p>I'm getting this error:</p><p>'HardwareSerial::HardwareSerial' is not a type</p><p>Thought it might be a missing library. Tried adding it, didn't help.</p><p>Any help would be hugely appreciated.</p>
<p>For anyone else that might run into this problem. Replacing </p><p>'HardwareSerial::HardwareSerial' with 'HardwareSerial' seems to work.</p><p>Good luck.</p>
<p>This is actually one of the most clear and complete instructables I have read so far!</p><p><br>Complimenti</p>
<p>Hi I am trying to get this oscilloscope working by problem is the python scripted Here is a picture of the problem script. The error it gives is &quot;missing parenthesis&quot; and I am not sure hoe to get this resolved. I hope to hear from you soon of how to fix the error.</p><p>https://www.dropbox.com/s/4zgbzaxtdb7szml/Problem.jpg?dl=0</p>
the parenthesis error is because u install Python 3xx and it was created for 2xx u need to do for all ... print fpwhat was befor naw become print (what was before), i hope is not too late.... i have some problems with libraries
hy there! first of all i whant to say nice job nice project!!! but i have some problems building the pcb, can someone help me with this? the pins that are used are confusing me... does someone have another scematic of this project, something i can understand or two pictures with the pcb one from the top and one from the bottom. thenks alot for the help
<p>Hi Caffeinomane,</p><p>My name is Joel Koenka, I'm a PhD student in the university of Basel.</p><p>I recently developed a Python GUI framework for Arduino-based instruments - &quot;Instrumentino&quot;.</p><p>You can read about it here:</p><p><a href="http://www.chemie.unibas.ch/~hauser/open-source-lab/instrumentino/index.html" rel="nofollow">http://www.chemie.unibas.ch/~hauser/open-source-la...</a></p><p>In the GitHub link you'll find the code and some documents.</p><p>I believe we can modify Instrumentino to fit your needs as a frontend for Girino.</p><p>I'm on my way these days for preparing instructables for installing and using Instrumentino, but it will take a while.</p><p>If you're interested, please contact me: yoel.koenka _at_ gmail.com</p><div></div>
<p>Hi all,</p><p>This <br> project is starting to getting old, but, for those still interested in, <br> I've developed a(nother) small Java GUI frontend to drive the Girino: </p><p>https://github.com/Chatanga/Girinoscope</p><p>It is not in pure Java since there is a native part to deal with the <br>serial communication, but it is the same as the one used by Arduino. <br>This way and provided you have a working Arduino IDE on your machine, <br>you should have no problem to run it on you Linux / Mac / Windows. Take <br>some time to look at the README file however since there is a lingering <br>problem with the 'wait duration' settings.</p>
<p>I&rsquo;ve released a new version which mostly fixes launching problems on Mac and Windows:</p><p><a href="https://github.com/Chatanga/Girinoscope/releases/tag/v1.0.1-beta" rel="nofollow">https://github.com/Chatanga/Girinoscope/releases/t...</a></p><p>I&rsquo;ve also tried the optimization described by womai and it has finally allowed me to unlock the x8 and x16 prescalers. Nice! The x4 prescaler is still out of reach, but I don&rsquo;t think the code could be optimized further.<br></p>
<p>Hi, I'm trying to use your program to interpret Girino data, which I have already configured properly. It works great!. I'm trying to do a bluetooth signal transmitter, the problem is that the program does not detect my bt receiver port (COM4). How can I solve this? Also, is there a way I can save the read data? Thank you very much for everything, especially for sharing your work, greetings!</p><p>PD. English is not my native language sorry if you have trouble understanding me.</p>
<p>Did you tweak the Girino code as stated by Womai? It should allow you <br>to use the &quot;yellow&quot; sampling frequencies. Regarding your problem with <br>Bluetooth virtual port, I didn&rsquo;t have a clue since I&rsquo;ve never tried to <br>use one. In theory, it should at least has been been detected by the <br>RXTX library. As a bluetooth device seems to actually create 2 ports to <br>communicate (one for reading, another for writing), having it working <br>without change in the Girinoscope is doubtful...</p>
<p>Thank you very much for your answer!, I will try the fix given by Womai (where do I have to put the code &quot;stopIndex = ADCBUFFERSIZE + 1;&quot;?). Returning to the bluetooth problem, when I try the python code written by Caffeinomane, it works very well and it detected the BT port and I can send data. But when I use your GUI, it only detected one of the two created bluetooth ports, the one that is not reading the Arduino. Also, is there a way I can save the read data using your program? Again, I thank you a lot for taking the time to answer.</p>
<p>**Patch:** at the begining of the sweep (case 's' in the loop function).</p><p>**Bluetooth:** try to add the &quot;-Dgnu.io.rxtx.SerialPorts=COM4&quot; option in the startup script.</p><p>**Data export:** you can&rsquo;t but it shouldn&rsquo;t be hard to implement... You need to capture a single frame or do you have some specific needs?</p>
<p>I 'm trying to make a signal transmitter using bluetooth. I need that the acquisition be as continuous as possible and I'm having this problem as you can see in the figure. In each sweep I have lost data. Do you know how can I solve this?. Regarding saving data I would need to be able to configure the saving time, for example 5 min o 30 sec, etc. </p>
<p>If you want to achieve fast continuous acquisition *and* transmission, the Girino (in fact the Arduino) won&rsquo;t be powerfull enough. Just think about Womai&rsquo;s tweak to unlock the highest capture frequencies: the Arduino is clearly 100% busy and hardly manage to simply store digital data. No way it can also send them through a serial connection in the same time. Doing both tasks should become possible at lower frequencies, but it would however require a significant refactoring of the Girino code. In fact, a more common configuration for a circuit doing continuous acquisition would be to use two specialized microcontrollers communicating using some kind of buffer.</p>
<p>Hi Guys</p><p>I would really like to get this project going as it looks fun and useful! I am getting an error message that I just can't get passed: java.io.IOExxception: Change has been rejected for parameter Threshold: 150 =/= 15. Do you know what it means?</p>
<p>Ok, I am passed the last error message but now I get Error 0x5...see picture.</p><p>I am running Windows 7 and using an Arduino Duemilanova. Any ideas?</p><p>Thanks</p><p>Dave</p>
<p>Did you patch your Girino code as stated in the README (https://github.com/Chatanga/Girinoscope)? If it the case, choosing a higher value for COMMANDDELAY could solve the problem (the communication protocol is not very elaborated).<br><br>Regarding your second problem, maybe you have a lingering java instance using your COM port?</p>
<p>Brilliant guide! Very clear explanations on key concepts, very thorough, and sets a great example on how to go about structuring a project like this.</p>
<p>Dear All,</p><p>Where can I find a bill of materials to build a girino-scope (I've the pdf file, but I don't want to forget anything) ?</p><p>I'm a biginner in electronics, and girino project is an interesting one that allows to learn many things.</p><p>Thanks</p><p>Paul</p>
<p>Hi</p><p>I'm a newby in electronics but I'm learning (hobby) ; girino is my first main project and I'm trying to understand the design of the (great) girino scope in order to build my own one ; after reading the different documents and the schematics, I do not fgure out some key point (especially in the double power supply). ...</p><p>I think the best thing is to find somebody than has ever built his one girino scope and can explain to me different things (in PM I think)</p><p>Thanks</p><p>Paul</p>
<p>Essentially, the Girino instructable is about how cleverly program the Arduino to achieve fast data processing. In that respect the supply list sums up to one single Arduino. Of course, another important part of an oscilloscope is the signal processing: offset, gain, impedance, protection... before safely injecting it into an arduino analog 5V pin. On the other hand, if your entry signal is already ok (per instance<br>if it is the output of another Arduino), you don&rsquo;t need most it (the only part truly needed is for the threshold signal). To quote the instructable:<br><br>The hardware that I added to the Arduino is partly necessary, its purpose is just to form the signal for the ADC and to provide a voltage level for the trigger. If you want, you could send the signal directly to the Arduino and use some voltage reference defined by a voltage divider, or even the 3.3 V given by the Arduino itself.<br><br>That being said, an entire instructable dedicated to this &quot;signal adaptation&quot; part would be great!<br><br>Regarding the dual supply, It is indicated that the -30/+30 V power supply is meant for the TL084 amp op. If you use the default LM324, the instructable says that you can use the 0/+5V of the arduino own power supply... That&rsquo;s not quite true. Granted, it will work for small amplitude signal, but with a full amplitude (0-5V), there will be distorsion. I&rsquo;ve personnaly powered mine with a ATX -12 / +12 V supply and it works fine. Using a pair of 9V batteries should be fine too (https://www.instructables.com/id/The-easiest-symmetrical-power-supply/). In fact, I don&rsquo;t even see the point of using the TL084. Granted it is faster than the LM... which is already too fast for the Arduino DAC. I guess there is some reason behind it I don&rsquo;t understand.</p>
<p>Great work thanks Chatanga and Caffeinomane. One glitch: the codes for the reference voltage are not correctly aligned between Girino and the GUI. I updated setVoltageReference(... in settings.cpp as follows:</p><p>switch (reference)</p><p>{</p><p>case 0:</p><p>cbi(ADMUX,REFS1);</p><p>cbi(ADMUX,REFS0);</p><p>break;</p><p>//case 2: correct mismatch with GUI</p><p> case 3:</p><p>sbi(ADMUX,REFS1);</p><p>sbi(ADMUX,REFS0);</p><p>break;</p><p>...</p>
<p>Right! I missed this one. The value used by the Girino is a bit misleading, but I&rsquo;ve released a new version whose code match the one used by Girino. This new version also introduces some UI refinements with more readable unit increments and the ability to change parameters while waiting for a trigger.</p><p><a href="https://github.com/Chatanga/Girinoscope/releases" rel="nofollow">https://github.com/Chatanga/Girinoscope/releases</a></p>

About This Instructable




More by Caffeinomane:Paper Embossing Girino - Fast Arduino Oscilloscope Celtic Knot Bone Pendant - Triquetra Pendant 
Add instructable to: