From 5a1cda7db7c4f96cb28cb0f0d2d22884a8652410 Mon Sep 17 00:00:00 2001 From: Rune Bekkevold Date: Fri, 22 Jan 2021 08:13:01 +0100 Subject: [PATCH 1/5] Delete main.cpp --- FW/src/main.cpp | 147 ------------------------------------------------ 1 file changed, 147 deletions(-) delete mode 100644 FW/src/main.cpp diff --git a/FW/src/main.cpp b/FW/src/main.cpp deleted file mode 100644 index f575c4e..0000000 --- a/FW/src/main.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/* - * This code demostrates a low frequency lockin amplifier or synchronous ligth - * detector inplementation using only a Arduino board and 2 additional modules: - * 1. Atmega328p Arduino board w synchronous detector inplementation in code - * 2. The OPT101 amplified vissible ligth photodiode - * 3. A laser pointer - * - * The syncronous detector components ar all realised in software - * using the Atmega328p builtin ADC as frontend. - * - * Basic spec - * ---------- - * ADC raw samplerate is 78.6kHz with estimated > 8 bit resoluition. - * LSB is a bit unstable becuse of the high samplerate but is giving better relative - * resolution wit this compared to lovering the samplerate and decimation ration - * ADC resolution is >14 bit after oversampoling and decimation - * Laser modulation or exitation frequency 12.8kHz, and so also the LO frequency of the sychronous detector. - * After decimation the output samplerate from the detector is 12.8 / 4^6 = 3.125 kS/s - * Ewerything is divided down and synchronous to the ADC raw samplerate clock. - * - * Copyright (c) 2020 Rune Bekkevold - * Released under the terms of the MIT license: - * https://opensource.org/licenses/MIT - * - */ - -#include - -// Analog input connected to the photo sensor -const uint8_t sensorPin = 0; -const uint8_t ExPin = 2; // Using D2 pin for Laser exitation output - -// ADC resolition ioncrease by oversampling an decimation -const uint8_t ADCincreasedRes = 6; // adding 6 extra bits ADC resolution -const uint16_t decimationFactor = (int)pow(4, ADCincreasedRes); // decimate oversampled data by 4^increasedRes - -// Light readings provided by the ADC interrupt service routine. -volatile int32_t lightReading; // Our detectir reading result goes here -volatile int32_t backGroundLvlReading; // Our ambient ligth measurement result goes here -volatile bool ligthReadingReady; - -// ADC interrupt service routine. -// Called each time a conversion result is available. -ISR(ADC_vect) -{ - // Read a sample from the ADC. - int32_t sample = ADC; - static uint16_t decimationCounter; - static uint8_t exitationCounter; - static uint32_t backgroundLvlAcc; - - static bool ExitationOn; - decimationCounter++; - exitationCounter++; - - // Mixer Function: - // Toggle exitation and sample sign as fast as possible inside our sensor bandwith - // Default 3dB bandwith for the opt101 is 14kHz so we need to be a bit slower than that - // This is a simple square wave mixer, I supose we could experiment with a sinewave LUT here - // but then how can we avoid floating point to make it fast enough? - if (!ExitationOn) - { // If exitation was off when the current sample was aquired, invert the sample sign - backgroundLvlAcc += sample; // lets also get a measurment of the ambient ligth level by averaging only the samples when the exitation is off - sample = -sample; // invert sample sign. this migth need some delay to aligne with the delayed responce from the sensor - } - - // Set up our exitation state for the next 6 samples - // because for 76.9 kS/s samplerate, division by 12 gives 6.41kHz on the exitation pin, - // so shold be well within the bandwith of the OPT101 sensor. - if (exitationCounter == 6) // toggle exitation every 6. sample - { - if (!ExitationOn) - { - PORTD = PORTD | 0b00000100; // set exitation pin D2 high - ExitationOn = true; - } - else - { - PORTD = PORTD & 0b11111011; // set exitation pin D2 low - ExitationOn = false; - } - exitationCounter = 0; - } - - static int32_t ADCsampleAccumulator; - ADCsampleAccumulator += sample; // sum up our samples for one decimation lenght - - if (decimationCounter == decimationFactor) - { // everytime sample counter reaches decimationFactor number of samples - if (ADCsampleAccumulator > 0) - { // Accumulator value is posiotve. cast acc to uint and rigthshift with virtual resolution invrease - lightReading = (int32_t)(((uint32_t)ADCsampleAccumulator) >> ADCincreasedRes); - } - else - { // Accumulator value is negative, flip sign and cast acc to unsigned before right shift - lightReading = -(int32_t)(((uint32_t)-ADCsampleAccumulator) >> ADCincreasedRes); - } - ADCsampleAccumulator = sample; // reset sample accumulator to previous sample; - - // get ambient light level - backGroundLvlReading = (backgroundLvlAcc >> (ADCincreasedRes - 1)); // the ambient level measurement is only haf the number of samples so we shist one bit less - backgroundLvlAcc = 0; // reset ambient Acc to 0 //(backGroundLvlReading >> ADCincreasedRes); - ligthReadingReady = true; - decimationCounter = 0; - } -} - -void setup() -{ - // Configure the ADC in "free running mode". - ADMUX = _BV(REFS0) // ref = AVCC - | sensorPin; // input channel - ADCSRB = 0; // free running mode - ADCSRA = _BV(ADEN) // enable - | _BV(ADSC) // start conversion - | _BV(ADATE) // auto trigger enable - | _BV(ADIF) // clear interrupt flag - | _BV(ADIE) // interrupt enable - | 4; //4 prescale 16 //5; // prescaler 32. 7; // prescaler = 128. - - // Configure the serial port. - Serial.begin(115200); - // configure Exitation pin mode and initial state; - pinMode(ExPin, OUTPUT); - digitalWrite(ExPin, HIGH); -} - -void loop() -{ - // Wait for interupt action to hsppen and saying a reading a reading is available. - while (!ligthReadingReady) /* wait */ - ; - - // Get a copy of the detecor result - noInterrupts(); - int32_t lighthReading_copy = lightReading; - int32_t backGroundLvlReading_copy = backGroundLvlReading; - ligthReadingReady = false; - interrupts(); - - // Transmit data. - Serial.print(backGroundLvlReading_copy); // Transmit detection level - //Serial.print(","); - //Serial.print(150); - Serial.print(","); - Serial.println(lighthReading_copy); // Transmit ambient level -} From 661b69c47bd8e94412b4b64a72859d4767b0bcab Mon Sep 17 00:00:00 2001 From: Rune Bekkevold Date: Fri, 22 Jan 2021 08:13:21 +0100 Subject: [PATCH 2/5] Delete platformio.ini --- FW/platformio.ini | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 FW/platformio.ini diff --git a/FW/platformio.ini b/FW/platformio.ini deleted file mode 100644 index 6374bcc..0000000 --- a/FW/platformio.ini +++ /dev/null @@ -1,18 +0,0 @@ -; PlatformIO Project Configuration File -; -; Build options: build flags, source filter -; Upload options: custom upload port, speed and extra flags -; Library options: dependencies, extra library storages -; Advanced options: extra scripting -; -; Please visit documentation for the other options and examples -; https://docs.platformio.org/page/projectconf.html - -[env:nanoatmega328] -platform = atmelavr -board = nanoatmega328 -framework = arduino - -monitor_speed = 115200 - -src_filter = +<*> -<.git/> -<.svn/> - - - - From b742a366081c10bd52a0a5df173d868cc99092dd Mon Sep 17 00:00:00 2001 From: Rune Bekkevold Date: Fri, 22 Jan 2021 08:15:15 +0100 Subject: [PATCH 3/5] Delete FW directory restructured. placed unfinished code in develop branch --- FW/.gitignore | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 FW/.gitignore diff --git a/FW/.gitignore b/FW/.gitignore deleted file mode 100644 index 71b08af..0000000 --- a/FW/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -.pio -.vscode -.vscode/.browse.c_cpp.db* -.vscode/c_cpp_properties.json -.vscode/launch.json -.vscode/ipch From a6b204d67e5255ab140bfde52415d70d3423ac80 Mon Sep 17 00:00:00 2001 From: Rune Bekkevold Date: Thu, 26 May 2022 22:22:49 +0200 Subject: [PATCH 4/5] updated specs --- specs/Analog_detector.png | Bin 0 -> 21081 bytes specs/Arduino_detector.png | Bin 0 -> 27042 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 specs/Analog_detector.png create mode 100644 specs/Arduino_detector.png diff --git a/specs/Analog_detector.png b/specs/Analog_detector.png new file mode 100644 index 0000000000000000000000000000000000000000..ae83d71d7c680e08a0bdda4d12ab65054d44566a GIT binary patch literal 21081 zcmeFZ^;cD0+cr#tbR)276{JyO(*gnl(%mIpo9@_jhX^PkARt|m(hbreots7)r1M={ zujhX5YrJE8CY8U5fEq*WL}G@c^K?xp!<+?pZEGd&*jr$rVBO@KcvM}c`b?Gb@Ez__(=OfWaW8Q zfDv+cAX6Y-1(|Ku2|m`i;F~afBxtbO8-_=}empq$)Ez%tc;bDS(d^F0e{;2t{3CdSgsA|9XdDXe z0(a-2WGXik*rJ$kJ3;1#<_S zkOK9{0pNyLzG|@kBo+)@+_E_R>5>s_P^wI^Lnk)qIu_5n7qbE>Rz09r)k99w9{VwP zea8yJrqTVdCxVC(a@c%9(P8NJp2P@M3(=dUt&Psm5e@e$b!W-M)|M3$3yXl9ywKZl zR!k!RxCNArfE?yCNe*7OvBrpM$}f}bSis`T3+Y&2KpxY--Fw2)h6#RyxTKQ6Aq0#j@9L0{DCJ5+?-mb#LkaMP zTLex>-?Z8VDZiE41)T}HHljvbJ0@@q5B_?29OHyKHEe=se`XEJMPQ8SC;JSQX!#mi z(bs1D|1c$8=6|Miz~(ewa3Ilz`wb9s5Qz~io(AFX*V8k`?1;SHqlM2^3lX@62>cQL z4JXNwbRAs^e;y!)f{(qPfumpdlG}$bvKr!hXJ_8plqyh<$95P(^ zs*Aeoxyp-S;Z%Rb2VW3Tgnz`kq{8+3_+KhSNJ0zq08|m5iYlhr`+}aCSys#cawUv_h$zVS z=KK-t@^US%Tef$m()4�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 literal 0 HcmV?d00001 diff --git a/specs/Arduino_detector.png b/specs/Arduino_detector.png new file mode 100644 index 0000000000000000000000000000000000000000..dd45c67284e2efd25f39539815131f714360cde8 GIT binary patch literal 27042 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 q0lS3fWAxYmn0-hKeSwp!1 literal 0 HcmV?d00001 From bb923ccc34a03832b071784de852f37b1fe94342 Mon Sep 17 00:00:00 2001 From: Rune Bekkevold Date: Mon, 20 Nov 2023 18:24:45 +0100 Subject: [PATCH 5/5] added Kicad project --- FW/.gitignore | 14 +++ FW/platformio.ini | 21 +++++ FW/src/main/main.cpp | 218 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 253 insertions(+) create mode 100644 FW/.gitignore create mode 100644 FW/platformio.ini create mode 100644 FW/src/main/main.cpp diff --git a/FW/.gitignore b/FW/.gitignore new file mode 100644 index 0000000..9bf248c --- /dev/null +++ b/FW/.gitignore @@ -0,0 +1,14 @@ +.pio +.vscode +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json +.vscode/ipch +*.sal +data.txt +liveplot.gnu + +<<<<<<< HEAD + +======= +>>>>>>> removeProcessing_from_ISR diff --git a/FW/platformio.ini b/FW/platformio.ini new file mode 100644 index 0000000..7d8325a --- /dev/null +++ b/FW/platformio.ini @@ -0,0 +1,21 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:nanoatmega328] +platform = atmelavr +board = nanoatmega328 +framework = arduino + +monitor_speed = 115200 + +src_filter = +<*> -<.git/> -<.svn/> - - - - - -
+ +;src_dir = src/application/ +;src = src/application/main.cpp diff --git a/FW/src/main/main.cpp b/FW/src/main/main.cpp new file mode 100644 index 0000000..1256bd9 --- /dev/null +++ b/FW/src/main/main.cpp @@ -0,0 +1,218 @@ +/* + * This code demostrates a low frequency lockin amplifier or synchronous ligth + * detector inplementation using only a Arduino board and 2 additional modules: + * 1. Atmega328p Arduino board w synchronous detector inplementation in code + * 2. The OPT101 amplified vissible ligth photodiode + * 3. A laser pointer + * + * The syncronous detector components ar all realised in software + * using the Atmega328p builtin ADC as frontend. + * + * Basic spec + * ---------- + * ADC raw samplerate is 78.6kHz with estimated > 8 bit resoluition. + * LSB is a bit unstable becuse of the high samplerate but is giving better relative + * resolution wit this compared to lovering the samplerate and decimation ration + * ADC resolution is >14 bit after oversampoling and decimation + * Laser modulation or exitation frequency 12.8kHz, and so also the LO frequency of the sychronous detector. + * After decimation the output samplerate from the detector is 12.8 / 4^6 = 3.125 kS/s + * Ewerything is divided down and synchronous to the ADC raw samplerate clock. + * + * Copyright (c) 2020 Rune Bekkevold + * Released under the terms of the MIT license: + * https://opensource.org/licenses/MIT + * + */ + +#include + +#define DEBUGPRINT 1; +#ifdef DEBUGPRINT + #define DEBUG_PRINT(x) Serial.print (x) + #define DEBUG_PRINTDEC(x) Serial.print (x, DEC) + #define DEBUG_PRINTLN(x) Serial.println (x) +#else + #define DEBUG_PRINT(x) + #define DEBUG_PRINTDEC(x) + #define DEBUG_PRINTLN(x) +#endif + +#define DEBUGPINS 1; +#ifdef DEBUGPINS + #define DEBUG_PIN_TOGGLE(x) PORTD ^= _BV(x); // Toggle pin + #define DEBUG_PIN_SET(x) PORTD |= _BV(x); // Set pin high + #define DEBUG_PIN_CLR(x) PORTD &= ~(_BV(x)); // Set pin low +#else + #define DEBUG_PIN_TOGGLE(x) + #define DEBUG_PIN_SET(x) + #define DEBUG_PIN_CLR(x) +#endif + + +// Analog input connected to the photo sensor +const uint8_t sensorPin = 0; +const uint8_t ExPin = 2; // Using D2 pin for Laser exitation output + +// Indicator pins for debugging +const uint8_t sampleIndicator = 3; // Indicator pin for sample rate +const uint8_t serialIndicator = 4; // Indicator pin for serial write +const uint8_t ADCisrIndicator = 5; // Indicator pin for ISR(ADC_vect) duration + + +// ADC resolition ioncreased by oversampling an decimation +const uint8_t ADCincreasedRes = 6; // adding 6 extra bits ADC resolution +const uint16_t decimationFactor = (int)pow(4, ADCincreasedRes); // decimate oversampled data by 4^increasedRes + +// - Exitation pulse length in number of ADC samples +const uint8_t exPulseLen = 16; + +// Light readings provided by the ADC interrupt service routine. +volatile bool ligthReadingReady; + +struct detectorRes { + uint32_t exitationLvl; + int32_t backgroundLvl; +}; +volatile detectorRes sampleSum; + +// ADC interrupt service routine. +// Called each time a conversion result is available. +ISR(ADC_vect) +{ + DEBUG_PIN_SET(ADCisrIndicator); //DEbug + // Read a sample from the ADC. + int32_t sample = ADC; + + static uint16_t decimationCounter; + static uint8_t exitationCounter; + static int32_t backgroundLvlAcc; + + static bool ExitationOn; + static int32_t exitationLvlAcc; + decimationCounter++; + exitationCounter++; + + if (!ExitationOn) // If exitation off + { + backgroundLvlAcc += sample; // Acumulate ambient ligth level + } else { + exitationLvlAcc += sample; // else Acumulate exited ligth level + } + + // store acumulators when decimationFactor number of samples is reached + if (decimationCounter == decimationFactor) + { + DEBUG_PIN_SET(sampleIndicator); + sampleSum.exitationLvl = exitationLvlAcc; + sampleSum.backgroundLvl = backgroundLvlAcc; + backgroundLvlAcc = 0; // reset ambient Acc to 0 + decimationCounter = 0; // Reset decimation counter + exitationCounter = exPulseLen; // Reset exitation counter + + exitationLvlAcc = 0; //sample; // reset sample accumulator to previous sample; + ligthReadingReady = true; // Tell that acummulators are ready for division + } + + // Toggle exitation every exPulseLen sample + if (exitationCounter == exPulseLen) + { + if (!ExitationOn) + { + PORTD = PORTD | 0b00000100; // Set exitation pin D2 high + ExitationOn = true; + } + else + { + PORTD = PORTD & 0b11111011; // Set exitation pin D2 low + ExitationOn = false; + } + exitationCounter = 0; + } + DEBUG_PIN_TOGGLE(ADCisrIndicator); + +} + +detectorRes sampleACCdownConvSimple() +{ + detectorRes results; + results.exitationLvl = (uint32_t)(sampleSum.exitationLvl / pow(2, ADCincreasedRes-1)); + + // get ambient light level + results.backgroundLvl = (int32_t)(sampleSum.backgroundLvl / pow(2, ADCincreasedRes-1)); // the ambient level measurement is only haf the number of samples so we shift one bit less + return results; +} + +detectorRes sampleACCdownConv() +{ + detectorRes results; + if (sampleSum.exitationLvl > 0) + { // Accumulator value is positive. cast acc to uint and rigthshift with virtual resolution invrease + results.exitationLvl = (int32_t)(((uint32_t)sampleSum.exitationLvl) >> ADCincreasedRes); + } + else + { // Accumulator value is negative, flip sign and cast acc to unsigned before right shift + results.exitationLvl = -(int32_t)(((uint32_t)-sampleSum.exitationLvl) >> ADCincreasedRes); + } + + // get ambient light level + results.backgroundLvl = (sampleSum.backgroundLvl >> (ADCincreasedRes - 1)); // the ambient level measurement is only half the number of samples so we shift one bit less + return results; +} + +void setup() +{ + // Configure the ADC in "free running mode". + ADMUX = _BV(REFS0) // ref = AVCC + | sensorPin; // input channel + ADCSRB = 0; // free running mode + ADCSRA = _BV(ADEN) // enable + | _BV(ADSC) // start conversion + | _BV(ADATE) // auto trigger enable + | _BV(ADIF) // clear interrupt flag + | _BV(ADIE) // interrupt enable + | 4; //4 prescale 16 //5; // prescaler 32. 7; // prescaler = 128. + + // Configure the serial port. + Serial.begin(115200); + + // configure Exitation pin mode and initial state; + pinMode(ExPin, OUTPUT); + digitalWrite(ExPin, HIGH); + + // Configure the other pins and initial states + pinMode(sampleIndicator, OUTPUT); + digitalWrite(sampleIndicator, HIGH); + + pinMode(serialIndicator, OUTPUT); + digitalWrite(serialIndicator, HIGH); + + pinMode(ADCisrIndicator, OUTPUT); + digitalWrite(ADCisrIndicator, HIGH); +} + +void loop() +{ + // Wait for interupt action to hsppen and saying a reading a reading is available. + while (!ligthReadingReady) /* wait */ + ; + + // Get a copy of the detecor result + //noInterrupts(); + //detectorRes detectorReadings = sampleACCdownConv(); + detectorRes detectorReadings = sampleACCdownConvSimple(); + ligthReadingReady = false; + //interrupts(); + DEBUG_PIN_TOGGLE(sampleIndicator); + + digitalWrite(serialIndicator, HIGH); + // Transmit data. + DEBUG_PRINT(detectorReadings.backgroundLvl); // Transmit detection level + DEBUG_PRINT(","); + DEBUG_PRINT(detectorReadings.exitationLvl); // Transmit ambient level + DEBUG_PRINT(","); + Serial.println((detectorReadings.exitationLvl - detectorReadings.backgroundLvl)/1); // Transmit detection level + + + digitalWrite(serialIndicator, LOW); + +}