JamesBremner / complot

High performance plotting of spectrum data from COM port
1 stars 0 forks source link

Static scatter plot with a fast refresh rate showing COM data #5

Closed JamesBremner closed 8 months ago

JamesBremner commented 8 months ago

Motivation in #4

JamesBremner commented 8 months ago

image

JamesBremner commented 8 months ago

Updated readme with specplotter usage and example

drmcnelson commented 8 months ago

Here is what a spectrum looks like

FluorescentLamp Screen

And here is one with the intensity of

FluorescentLamp Screen Noise turned down so that we can see the noise.

drmcnelson commented 8 months ago

Those are 3600 points each.

JamesBremner commented 8 months ago

If you want 3600 points, set the frequency count to 3600. ( Please read the usage docs https://github.com/JamesBremner/complot/blob/main/README.md#usage )

drmcnelson commented 8 months ago

The frequency control seems out of place as a graph parameter. What defines the graph should be a pair of vectors, x and y. After an x vector as been supplied, we can update with a new y.

JamesBremner commented 8 months ago

The frequency control seems out of place as a graph parameter.

Do you mean the frequency count? This is used to determine how many points to read from the COM port.

drmcnelson commented 8 months ago

Yes, you are taking that much data per pass and graphing it. But you are treating them as a time series, and graphing them one after the other across the graph. That is not what the data is. One set of points should fill the graph.

drmcnelson commented 8 months ago

Aside, just in case, it might be mentioned that the number of points is not necessarily going to be less than the number of pixels

JamesBremner commented 8 months ago

One set of points should fill the graph.

Yes. The size of the set is the frequency count. The number of different frequencies measured by your device,

drmcnelson commented 8 months ago

See the image of the spectrum in the message above. That is what each set of points should produce

JamesBremner commented 8 months ago

the number of points is not necessarily going to be less than the number of pixels

Yes. That is what the scaling does. As I mentioned, plotting is never simple.

drmcnelson commented 8 months ago

Oh, is that what your a graphing? You have a set of bars and they repeat. So I guess that full set is one spectral frame?

JamesBremner commented 8 months ago

Have you built and run the demo? That should make things clearer for you.

drmcnelson commented 8 months ago

Okay, if that is the case, then I need to plumb the call into my app, I am about to try it actually. I spend the day on the ring buffer. There will be a pointer to the last read spectrum, and some increment and decrements to look around the ring.

drmcnelson commented 8 months ago

I have read the app, I have not run it because I dont have the virtual connection tool. I looked into getting it but it was not so clear how to set it up and use it. And I am under pressure to finish my own app.

drmcnelson commented 8 months ago

Your paradigm for reading the data is very different from mine. But in the end you have an array with the data and you call set(), as I recall. So that is what I need to implement. I should have something running soon.

drmcnelson commented 8 months ago

Please stand by, I will send you something in just a moment.

JamesBremner commented 8 months ago

I think you mean the virtual null modem. It is trivial to setup. https://www.aggsoft.com/virtual-null-modem.htm

It is almost impossible to develop and debug COM applications without this tool.

drmcnelson commented 8 months ago

I have the hardware spectrometer. This is how the spectrometer sends the data


     void sendBuffer_Binary( ) {
           uint16_t *p16 = &bufferp[DATASTART];
           Serial.print( "BINARY16 " );
           Serial.println( NPIXELS );
           Serial.write( (byte *) p16, NBYTES );
           Serial.println( "END DATA" );
     } 
drmcnelson commented 8 months ago

This is the controller board for the spectrometer, it is missing a connector so I use it as a labrat for coding.

IMG_20240213_170340389 600

drmcnelson commented 8 months ago

16bit 1MS/s ADC connected by SPI. So we read a 2048 pixel line from the CCD in about 2 milliseconds. The upload to the host over 480MHz USB takes less than 100 usecs. So this one actually runs a bit faster than 100 sensor frames/sec. Graphics of course is not expected to keep up. But the dedicated thread that reads it to a ring buffer, does keep up. The graphics catch up later. We only burst for 100 frames at an instance.

JamesBremner commented 8 months ago

I do not know what you expect me to do with all that info.

This issue is assigned to you in test. Please test it and either close it or describe any snags you find.

drmcnelson commented 8 months ago

I thought you might like to see the context.

But, this here, how the spectrometer sends the data, I think is relevant. https://github.com/JamesBremner/complot/issues/5#issuecomment-1942711071

In any case, I should be testing soon. From the timer event handler, it just needs to pick up the pointer to the current frame. I am generating one on startup.

JamesBremner commented 8 months ago

What is sendBuffer_Binary?

I would appreciate it you would describe the data you send, in the way I asked you before or equivalent https://github.com/JamesBremner/complot/issues/4#issuecomment-1939709138

JamesBremner commented 8 months ago

Looking at the code fragment you posted, I have the idea that you are sending your data as 16 bit integers.

Is this correct?

If it is, then please open an issue for that and I will convert the demo to transmit those ( currently it uses 64 bit floats ) This will be a lot more efficient.

drmcnelson commented 8 months ago

That is probably a good idea if someone wants to use it that way.

For the spectrometer it has to be used as a larger type. The reason is because it is very common to do signal averaging (element wise addition) for hundreds of frames, to improve signal/noise. 16 bit integers will overflow right away.

Since I am storing it to a larger type anyway, I might as well convert it to voltages at the same time. After all it comes from an ADC.

                       for (n = 0; n < npixels; n++)
                        {
                            data[n] = rawbuffer[n] * volts_per_lsb;
                        }

where data is double.

JamesBremner commented 8 months ago

So you are not using 16 bit integers despite the uint16_t in your code fragment.

OK, what are you using? ( I am getting really sick of asking this question over and over. It could hardly be simpler, you you keep on dodging giving me a straight answer. )

drmcnelson commented 8 months ago

P/S the point of the code fragment, was the unit of transmission, one linear ccd frame = all the pixels across the row in the sensor, with a message before and after.

I dont think it is relevant to duplicate that protocol in a demo. I just wanted to show you what I mean by a frame and what is the unit of information to be graphed.

I think this a sort of not unusual user case for scientific graphics.

JamesBremner commented 8 months ago

I dont think it is relevant to duplicate that protocol in a demo.

OK, closing this issue.

Going offline

drmcnelson commented 8 months ago

No I am not dodging, I think we have different contexts and terminology.

Ok, thank you.

JamesBremner commented 8 months ago

Since you have refused to tell me how long your data points are, I have added a user option to select different lengths. Currently implemented are 8 byte doubles and 2 byte unsigned integers.