Close

A quick fun test with better filters..

A project log for ramanPi - Raman Spectrometer

The open source 3D Printable Raman Spectrometer using a RaspberryPi and easy to find off the shelf components..

flcfl@C@ 08/18/2014 at 03:362 Comments

Ok, so I totally re-wrote the code for the CCD driving..  I actually totally removed the PWM driver for the ICG line and replaced it with a sort of state machine driven by the Shift Gate...  So, now the firmware tracks the pixel position and what types of pixels it's reading so it can make decisions about what to do with the incoming data from the analog port.  I haven't got so far as to actually buffer the data (right now it's dumping it to the serial port at 921600baud, which isn't quite fast enough)..  I would like to store the data in memory and dump it every cycle, or when it's requested.  I'll get there.. I need to write some python code to generate a graph based on that data too.. I'd love to get the remote rpc over serial working, but the mbed platform doesn't seem to support that on the Nucleo boards yet... I'll get there too...  But for now, the filters I ordered from Amazon this morning (Sunday) arrived this afternoon (Sunday).. Amazing is what they should be called.  Anyway, I took a minute to make these pics...I know I said I was going to try and capture real world pics of the CCD face to compare to each, but my camera just doesn't do that too well.. At least the one on my galaxy.. I'll try another camera when I can..Maybe my gopro will do better..  

There's a lot of scope captures if you click the read more! 

So, these filters are a LOT better..  Here's the results..

This is just the CCD at idle..no light source and no filters... I couldn't seem to get it dark enough..  =/

This is just the grey filter with the light source on...  All the remaining captures have this grey filter added on because I couldn't get the light level low enough.. I could have adjusted the slit..but I didn't want to get that involved for this short test.

Here is purple...

And then blue..

Next we have green..

And perhaps brown..?

Then we'll go with yellow...!

And how about we throw in some pink..?

And finally we have red...  :)

Here is a pic from Amazon of the filters used for this... Standard 52mm camera filters...

And just for good measure... and for those who would rather look here than go to the gitHub or mBed repo... The code I used for these...  If anyone has any good suggestions on how to go about buffering the data, or getting the rpc over serial to work...I would love to hear it!!

#include "mbed.h"


//  ***   BE SURE TO TEST BEFORE AND AFTER FOR 'IDLING'... CLEAR THE CCD EVERY OTHER FRAME TO TRY AND ELIMINATE NOISE BUILDUP
//From <a href="http://www.ing.iac.es/~docs/ins/das/ins-das-29/integration.html">http://www.ing.iac.es/~docs/ins/das/ins-das-29/integration.html</a>
//"Idling" vs. integrating
//Charge from light leaks and thermal noise builds up on the detector between observations. If this charge is integrated by the detector, it may not be completely
//cleared away by the clear cycle of the next observation. In that case, the observation will be contaminated by extra counts. (Often, this appears as a ramp in the
//background leading up to a saturated region in the low-numbered rows.)
//To avoid this problem, the detector is made to clear itself continuously between observations. This is called "idling", and is reported as such on the mimic.


PwmOut masterClock(PB_4);
PwmOut shiftGate(PB_8);
InterruptIn shiftGate_int(PC_6);
//PwmOut icg(PB_3);
DigitalOut ICG(PB_3);
//interruptIn icg_int(PB_3);
AnalogIn imageIn(A0);
//AnalogOut imageOut(A5);
DigitalOut LED(LED1);
Serial raspi(USBTX, USBRX);


int masterFreq_period       = 2;      //microseconds
int masterFreq_width        = 1;      //microseconds
int shiftGate_period        = 200;    //microseconds
int shiftGate_width         = 100;    //microseconds


int none        = 0;
int veryLow     = 1;
int low         = 100;
int medium      = 100000;
int high        = 1000000;
int veryHigh    = 10000000;


double imageData;
int sensitivity             = none;
int pixelTotal              = 3694;
int leadingDummyElements    = 16;
int leadShieldedElements    = 13;
int headerElements          = 3;
const int signalElements    = 3648;
int trailingDummyElements   = 14;
int pixelCount;
int readOutTrigger;
int state;


#define readOut_Begin               1
#define readOut_ACTIVE              2
#define readOut_LeadingDummy        3
#define readOut_LeadingShielded     4
#define readOut_headerElements      5
#define readOut_signalElements      6
#define readOut_trailingDummy       7
#define readOut_integrationTime     8
#define readOut_IDLE                9
#define readOut_Finish              0


#define MV(x) ((0xFFF*x)/3300)


float pixelValue[signalElements];


void error()
{
    while(1) {
        LED = !LED;
        wait(0.5);
    }
}


void checkState()
{
    if (readOutTrigger == 1) {
//        state = readOut_LeadingDummy;
    }
    switch (state) {
        case readOut_Begin:
            readOutTrigger = 1;
            state = readOut_ACTIVE;
//            ICG = 1;
            LED = 1;
            break;
        case readOut_ACTIVE:
            ICG = 1;
            state = readOut_LeadingDummy;
            break;
        case readOut_LeadingDummy:
            pixelCount++;
            if (pixelCount == leadingDummyElements) {
                pixelCount = 0;
                state = readOut_LeadingShielded;
            }
            break;
        case readOut_LeadingShielded:
            pixelCount++;
            if (pixelCount == leadShieldedElements) {
                pixelCount = 0;
                state = readOut_headerElements;
            }
            break;
        case readOut_headerElements:
            pixelCount++;
            if (pixelCount == headerElements) {
                pixelCount = 0;
                state = readOut_signalElements;
            }
            break;
        case readOut_signalElements:
            pixelCount++;
//            pixelValue[pixelCount] = imageIn.read();
//            imageData = ((imageIn.read_u16() * 5.0) / 4096.0);
            raspi.printf("%4.12f \r\n", (imageIn.read_u16() * 5.0) / 4096.0);
            LED = !LED;
            if (pixelCount == signalElements) {
                pixelCount = 0;
                state = readOut_trailingDummy;
            }
            break;
        case readOut_trailingDummy:
            pixelCount++;
            if (pixelCount == trailingDummyElements) {
                pixelCount = 0;
                state = readOut_integrationTime;
                ICG = 0;
            }
            break;
        case readOut_integrationTime:
            wait_us(sensitivity);
            state = readOut_Finish;
            raspi.printf("---\r\n");
            break;
        case readOut_Finish:
            state = readOut_IDLE;
            wait_us(sensitivity);
            LED = 0;
            ICG = 1;
            break;
        case readOut_IDLE:
            if (ICG == 1) {
                ICG = 0;
                state = readOut_Begin;
            }
            break;
        default:
            break;
    }
}


int main()
{
    ICG = 1;
    LED = 0;
    pixelCount = 0;
    readOutTrigger = 0;
    state = readOut_IDLE;


    masterClock.period_us(masterFreq_period);
    masterClock.pulsewidth_us(masterFreq_width);


    shiftGate.period_us(shiftGate_period);
    shiftGate.pulsewidth_us(shiftGate_width);


    raspi.baud(921600);
    wait(0.5);


    shiftGate_int.rise(checkState);


    raspi.baud(921600);
    while(1) {
        wait(1);
    }
}

Discussions

A. M. Aitken wrote 08/18/2014 at 08:53 point
Looking good, what are you going to use for fine focusing, a neon bulb?

  Are you sure? yes | no

fl@C@ wrote 08/18/2014 at 11:39 point
Thanks Marvin..! I was thinking about that... Neon seems like the most readily available....and cost effective. I was wondering about a tungsten halogen... I'm not sure how good a projector bulb or something would be....or a TH car headlamp...
I still have a lot of backend work to do before I get there though.. I've been working all night on getting python to plot the data coming from this nucleo... I'm a bit rusty.. ;)

  Are you sure? yes | no