Pololu Robotics & Electronics
Menu
My account Comments or questions? About Pololu Contact Ordering information Distributors

Pololu Forum

Data Output for SLO Scope


#1

So I have really been loving the SLO Scope application, its great tool for analyzing and debugging small projects.
I must admit though that there is one small add on that I really wish could be added to the application. I want to store the data that is measured in something other than a picture. I was able to get the source code for the application (from this site) and have been looking through the application for a place to insert the output ‘append datapoint to text file’ code line.
I was able to get some output from the SLO scope application. By this I mean I was able to extract the data points of the ‘large’ graph, however I really am after is a constant stream of data.
Has anyone else done this? I would really appreciate help on where in the application I need to place my code to get ALL SLO scope recorded data.
Would really appreciate any input.
Thanks
Chris


#2

Hello, Chris.

The method ReadExisting of the RawData class in the SLO-scope client C# source code is responsible for reading data from the SLO-scope and storing it in a ring buffer. I think you should insert some code right after the call to sloscope.read in order to do something with the data. Your code should look something like this:

public int ReadExisting()
{
    int readingsCount = (int)sloscope.read(buffer, Sloscope.ReadMode.Existing,
        (uint)bufferPosition, (uint)(Size - bufferPosition), 1);
    for (uint i = 0; i < readingsCount; i++) {
        // Write buffer[bufferPosition + i] to a file
    }
    bufferPosition = (bufferPosition + readingsCount) % Size;
    // ...
}

Please let me know if you have any other questions.

–David


#3

Hi David,
Firstly thanks so much for your quick response.
I am currently at work however i believe i tried inserting my append to text file code in that method but then only got the ‘raw’ data value. Its been a while since i did any C# coding, so how do I then call the countspervolt to convert the counts from the ring buffer to ‘actual volts’. I tried just throwing it in there it but got an error saying countspervolt is not define (which makes perfect sense since it can’t find the variable in that RawData class… so how do i make it see that countspervolt method in the Form1 Class. If i remember correctly the countspervolts is in the Form1.cs…?
But thanks again for pointing me in the right direction.
Looking forward to your response.
Cheers
Chris


#4

Hi David,
So i tried putting in my code where you mentioned and it does write to my text file on a continuing bases which i am happy about, however I am not getting any readings out…
This is my new version of the ReadExisting()

    public int ReadExisting()
    {
        int readingsCount = (int)sloscope.read(buffer, Sloscope.ReadMode.Existing,
            (uint)bufferPosition, (uint)(Size - bufferPosition), 1);

        string path = @"c:\SLO-Scope\SLO-Scope-Data --- " + DateTime.Now.ToString("dd-MM-yyyy hh.mm tt") + ".txt";

        for (uint i = 0; i < readingsCount; i++)
        {
            // Write buffer[bufferPosition + i] to a file

            
            using (StreamWriter sw = File.AppendText(path))
            {

                sw.WriteLine(DateTime.Now.ToString("hh.mm.ss.fff") + " Channel A: " + buffer[bufferPosition + i]);                                                                                                           

            }
        }
        bufferPosition = (bufferPosition + readingsCount) % Size;

        // sloscope.read() isn't set up to write data into a ring buffer, so if we reach the end of the array, we
        // need to perform a second read starting from the beginning of the array to be sure we get all the data
        while (bufferPosition == 0)
        {
            bufferPosition = (int)sloscope.read(buffer, Sloscope.ReadMode.Existing, 0, (uint)buffer.Length, 1);
            readingsCount += bufferPosition;
            bufferPosition = bufferPosition % Size;
        }

        return readingsCount;
    }

From the above Code i get the following output in my SLO-Scope-Data… .txt file

Start
05.11.48.787 Channel A: Pololu.Sloscope+Reading
05.11.48.787 Channel A: Pololu.Sloscope+Reading
05.11.48.787 Channel A: Pololu.Sloscope+Reading
05.11.48.787 Channel A: Pololu.Sloscope+Reading
... and so on

Where am i going wrong? Shouldn’t i get the buffer values?

Thanks
Chris

PS i create the .txt file as shown below

 private void Form1_Load(object sender, EventArgs e)
        {

            string path = @"c:\SLO-Scope\SLO-Scope-Data --- " + DateTime.Now.ToString("dd-MM-yyyy hh.mm tt") + ".txt";
            if (!File.Exists(path))
            {
                // Create a file to write to.
                using (StreamWriter sw = File.CreateText(path))
                {
                    sw.WriteLine("Start");
                }
            }

            // Add the current version numbers to the Window's title bar
            if (System.Deployment.Application.ApplicationDeployment.IsNetworkDeployed)
                this.Text += " (" + System.Deployment.Application.ApplicationDeployment.CurrentDeployment.CurrentVersion + ")";

            // Attempt to connect to the SLO-scope
            try
            { //...

#5

Hello, Chris.

It looks like you are trying to open a file, append a line to it, and close it for every single reading. This is not practical because you will be getting 10000 or 20000 readings every second. I am pretty sure you will need to open the file in advance (e.g. in the constructor of RawData) so it is already open when the readings come in.

I am not very familiar with how C# converts objects to strings, but in this case it decided to convert the buffer[bufferPosition + i] object (which has type Pololu.Sloscope.Reading) to the string “Pololu.Sloscope+Reading”. Instead of relying on the default C# implementation to convert that object to a string, you should either write your own function to convert the object to a string or you should directly access the members of the Reading object (buffer[bufferPosition + i].channelA and buffer[bufferPosition + i].channelB).

–David


#6

Hi David,
Following up,
Using the "(buffer[bufferPosition + i].channelA " really worked well. I am returning the counts correctly now.
I noticed that since its running through that method about 21 times a second I could just limit the number of readings that gets placed into the .Txt file per ring buffer reading, so instead of i++, maybe only count every 10th or 100th or even 1000th value, or i could even just get the single last value measured.
I do have one last question,
What do I have to change to use the countspervolt method in the RawData class located in Form1 (hope that made sense)? Can i make it like a global method?
Thanks
Cheers
Chris


#7

I simple solution would be to assume that countsPerVolt is 205, and then just divide by that number before printing your result. It is important to write it as 205.0 so C# knows that you want a floating point result from the division instead of an integer. So right after .channelA you would insert / 205.0.

Typically countsPerVolt will actually be a little higher than 205; it depends on the voltage of your USB port, the voltage drop due to resistance in your USB cable, and the voltage drop of a diode on the programmer.

If you want a more accurate value for countsPerVolt, I would suggest moving GetMillivoltsPerCount from the Form1 class to the Sloscope class. Then you could run it in the constructor of the RawData class and store the countsPerVolt in that class. Or you could just print out the countsPerVolt value from Form1 and then hardcode it into the RawData class.

–David


#8

Hey David,
Awesome Thanks so much for the support. I ended up just copying the countspervolt method over and using it in the RawData class.
Works very well.Thanks again for all the help.
Cheers
Chris