We are about to switch to a new forum software. Until then we have removed the registration on this forum.
I am working on a science project with my son that involves generating a force as a function of time plot. My idea is to modify the LittleBits EtchAsketch code for this purpose. Accordingly, I would like to know how I could modify the EtchAsketch processing code to measure time along the x-axis. Moreover, I would like to show the numerical values on the vertical and horizontal axes and keep the measured signal. The LittleBits Arduino is based on the Lenoardo board. Any help is welcome. Thanks!
Answers
Can you provide a link to the code? It will be great if you comment about your experience with processing (or programming) so people can address your question accordingly.
Kf
Sorry, the link can to both the processing code and arduino code can be found here: http://littlebits.cc/projects/diy-etch-a-sketch . I am a beginner in terms of writing code. I have only made slight modifications to code, but I have never written code from scratch.
Hi @trinity
There is a good example that you can use for drawing your input data. In the Processing IDE, go to menu File>>Examples and then click on Basics>>Inputs>>MouseSignals and you will see a cool sketch of plotting mouse signals over the width of the screen. The width of the screen projects time in this example. Now, this example will not work right away as you will need to modify it to suit it to your needs. In the code below I have attempted to write snippet that you could use with your Arduino. However, please keep in mind I didn't have the chance to test it on an actual device. I generated my own data for debugging purposes. Check it out and let me know if you have any questions or issues there. Notice this example is heavily modified from the website you provided. I manage serial incoming data using provided functions from the Serial library. You should be able set any screen size at the beginning of your sketch and the code should work.
Kf
Thanks, I will try it out and let you know if it works!
The code seems to measure time by the second, but it is not plotted with what we measure on the y-axis. In fact, there are no values plotted on the y-axis. It would also be convenient to record the time with 10 ms resolution. Do you have any suggestions?
You need to remember I do not have a system with me so you need to be more specific of what you need. As far as I know, you are reading two sensors, from what I saw in the original pde file. The code above takes those two sensors' inputs and plot then over time. However, time here is not time as in seconds, but relative time as data arrives and gets processed by Processing.
There are three ways to interpret time:
float currentTime=index*frameRate();
This gives time as measured from the left side of the screen, the left side being 'zero' seconds. This method is not totally accurate but enough for your application. Notice this time is reset every time the data reaches the right end of the sketch.float currentTime=frameCount*frameRate();
Time relative to the beginning of the program. Not accurate but enough for demonstrations.Another way to get relative time is using
int currentTime=millis()
right when the lines are drawn. This time is in milliseconds and is relative to the start of the program.For line 55 and 56, you need to change the LRange and HRange values in that function. You choose the values based on the range of your input data. If it is an accelerometer with 10 bit resolution, it means it can output data from 0 to 1023 (total number of entries is 1024 or 2^10 where 10 is related to 10 bits). However I don't know what sensor you are using and what is their output range. This information is provided in your sensor's data sheet (or specification sheet).
To see if it is working, or if you are receiving data, introduce this next line in the previous code at line 54:
println(millis()+"Processing idx="+index+" "+valuesx[index]+" "+valuesy[index]);
Let your sketch run for about 5 seconds. Copy and paste here what you get from the console. To do that, slect the text in the console and hit ctrl+c to copy. You can paste it here in the forum with ctrl+v.Kf
COM3
After adding the println in the last posted code, you don't get any other data, just COM3?
Kf
Correct.
Although it was able to run both times (before and after adding line 54) there were some errors. Perhaps, if I correct the two errors, I will see more.
What do the errors say? Please copy and paste those errors here.
Kf
Type String[] of the last argument to method println(Object...) doesn't exactly match the vararg parameter type. Cast to Object[] to confirm the non-varargs invocation, or pass individual arguments of type Object for a varargs invocation. line 30 The value of the parameter serial is not used line 62
Please. paste your code here.
Kf
I did not modify your code. I just copy-pasted it and ran it.
Make sure this line is enable in line 54:
println(millis()+"Processing idx="+index+" "+valuesx[index]+" "+valuesy[index]);
You should see lots of lines being print out in the console.
Change the function in line 62 for this
Kf
It seems to work now as intended; however, perhaps I did not make everything clear. We only need one input, not the two from the little bits sketch. Nevertheless, it is collecting data. I was wandering if it is possible the have the start recording once an in input voltage is detected and stop when it is not? This is the time that we need, as well as the maximum detected voltage. Thanks again for all of your help!!!
That will required few more lines of code and to know exactly what sensor you are using on your arduino unit. After you collect the data, you can use a function like max() on your stored values. To trigger data collection, you need to know the output range of your sensor in order to define when an
input voltage is detected.
Kf
I am currently using a1, perhaps it is value x. However, I could switch to either terminal a1 or a0. The values range from 0 to 5 volts.
@trinity
Do you have an Arduino UNO or the same as in the link, a Leonardo version?
Kf
It is a Leonardo board.
Check this code. You need to adjust the value of swTRIGGER which is the software trigger that enables data collection. Right now I set the value to 25% of the maximum input (25% of 10 bits, in other words, 0.25*1024=256 which is 25% * 5V= 1.25V
When the input of interest goes below the threshold, data collection stops, the data is saved in a file that you enter and the program will exit.
Data stored is in 3 columns following the the format "time,dataX,dataY", where the time is in seconds.
Please keep in mind I didn't run the code with an Arduino unit. However it was tested with the artificial data generation function included.
Kf
************EDITED line 149
line 86 gave me the following error message: ArrayIndexOutofBoundsException:-1
@trinity
Please move line 70 to after line 72.
Kf
I will make this change, but I forgot to mention that there was a similar message as before:
Type String[] of the last argument to method println(Object...) doesn't exactly match the vararg parameter type. Cast to Object[] to confirm the non-varargs invocation, or pass individual arguments of type Object for a varargs invocation.
The value of the parameter serial is not used
Line 149 should be:
Is that where the error points to?
Kf
No, the error was at lines 48 and 139.
The line 149 addition has some errors, but it will run with the previous correction. However, it does not begin with the threshold voltage; but rather, it is continuously running as before.
Sorry, I meant to say line 139, not 149. So now it is working?
Kf
Yes, it seems to be working, but it is giving the start time and not the duration of time, i.e. start input to end input.
Line 149 above is an empty line, so I am not sure what line you are referring to. Notice that warnings are not a problem when running any code. Please copy and paste your error message here. In regards to the program running continuously, it is because the input data is always above threshold and never goes under threshold. I suggest you tweak the threshold percentage from 10% to 90%. That is, in line 19 in the previous post with code, instead of 0.25, try values between 0.10 to 0.90.
If you have any problems, send me a private message with your latest code. Please format the code before you send it.
Kf
When you open the file, duration is calculated by taking the last time and subtracting the first time.
Kf
Type String[] of the last argument to method println(Object...) doesn't exactly match the vararg parameter type. Cast to Object[] to confirm the non-varargs invocation, or pass individual arguments of type Object for a varargs invocation. line 48
The value of the parameter serial is not used line 139
I think I did not notice the duration, because the time resolution is one second.
@trinity
I believe these are warnings. Your program still runs, doesn't it?
Regarding duration, if you see line 96 and 126, I am saving time in milliseconds, so if your event is less than one second, you could still measured this time. Just take the time from the last entry and subtract the time from the first entry and then divide the number by 1000 to convert the duration to seconds. Please notice an error when I print the file header in line 123. It should be this instead:
output.println("Time[msecs],dataX,dataY");
Notice the change from [secs] to [msecs].Kf
The data in the console is still being recorded with second resolution. I cannot see any decimal places. Should I make a change to line 67, 88, and/or 107?
The file you saved contains the data in milliseconds. After you run the file and save the data, open the file. The file should have three columns separated by commas. The data is saved as indicated in line 126. Last time stamp minus first time stamp should give you duration. Please send me the content of one of your files through a private message. To do so, click my ID name here in the forum and then click on the message button.
To display the data in seconds with decimal points, please change line 88 to
println("Data collection started at "+millis()/1000.0+" seconds");
Notice the decimal point for the 1000.0 divisor. Implement the same change in line 107.Kf
Yes, it is now showing millisecond time resolution. Thank you very much!!!
@trinity, you are very welcome. Good luck with the project!
Kf
Sorry, but it appears that the time duration is less than 1ms. The sensor can measure down to 1 microseconds. Do you think this arduino can measure 0.1 ms or less?
I don't have experience to work with faster sampling rates in Arduinos. I found this link. Have you implemented changes in your arduino code to handle faster sampling rates?
http://forum.arduino.cc/index.php?topic=6549.0
Link to a general search: https://www.google.ca/search?q=arduino+sampling+rate&rlz=1C1CHWA_enCA688CA688&oq=arduino+sampling+rate&aqs=chrome..69i57j0l5.3753j0j7&sourceid=chrome&ie=UTF-8#q=arduino+leonardo+sampling+rate&*
Kf
No, I did not try changing the code, because I was not sure where it should be modified.
Can you post your arduino code?
Kf
@trinity I was referring to your arduino code. This is the processing code.
Kf
There is this more recent post that could be useful:
http://yaab-arduino.blogspot.ca/2015/02/fast-sampling-from-analog-input.html
One of the contributors shared his code: https://drive.google.com/file/d/0B6PxDhwK5tSJaTFka254WUk1NjA/view?usp=sharing
I have a limited exposure to arduinos and trying to push it to higher sampling rates could be a tricky business if these samples codes don't work out of the box. I would suggest you ask this more technical questions on an Arduino forum.
Of importance, you need to know about your sensors that you are reading from the arduino as that is probably the first thing one would like to know.
Can you tell me more about your event that you are trying to measure? I am curious...
Other reference links (more for the record):
https://www.arduino.cc/en/Reference/PortManipulation
http://forum.arduino.cc/index.php?topic=6549.15
Kf
Essentially, an object is launched at a target, which is a pressure sensor. We are trying to determine the speed of the object using its change in momentum. I have placed foam behind the target; however, it does not stop the object completely. Accordingly, I have decided to make some changes to my device set-up in order to increase the contact time. I will add clay to the foam, in order to stop the object from moving backwards. This should also increase the contact time between the object and the pressure sensor.