How can I read an array of values from the ADC through a single channel on an STM32 (Nucleo F401RE)?
I am trying to work with the TCD1304DG Linear Array (CCD) sensor. I have configured the signal timings perfectly, as shown in the datasheet. Here is an image from the datasheet of the necessary signals for driving the sensor:
And here is a screenshot of my logic analyzer window, replicating the displayed signals:
I have never worked with the STM32 ADC before so I am kinda lost right now. I am trying to operate the sensor as shown in this image:
My Question: Given the timing requirements and the timing chart, how can I configure my Nucleo F401RE board's ADC to work with this system, so that I have an array of 3694 elements (corresponding to the 3694 pixels) to transmit to my host computer for further processing and visualization?
Here is what I have tried so far:
while (1) {
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
for(uint16_t i = 0; i < 3694; i++) {
CCDPixelBuffer[i] = HAL_ADC_GetValue(&hadc1);
}
}
This does not work, however. I would appreciate any guidance regarding this sensor, or if you've worked with any other linear array sensor. I just want to know how to read the values into the ADC. I can work with very basic potentiometers, but I have no idea how to configure this to work with the ADC.
Please let me know if you need more information to understand my issue.
References:
Here is the link to the tutorial which I followed: https://curiousscientist.tech/blog/tcd1304-linear-ccd-driving-the-ccd
Hardware Setup
This is the typical drive circuit, shown in the datasheet:
This is a more detailed schematic of my circuit (I have not implemented the PSU module):
This is my setup:
I am not using the HEX inverter (74HC04) because I am able to invert the signals at the source so I didn't find it necessary.
Here is a GIF I made of the sensor output when I tried to visualize it with the ADC configured with DMA. The exact configuration of the ADC can be found in the tutorial link I provided above.
The two vertical bars in the GIF are meant to be the dummy pixels which are shown in the datasheet. The real measurement exists between these peaks. When I put something on the sensor, I am able to notice that the sensor detects it. But I expect the output to be in such a way that pixel-1 should always have the index buffer[0] and pixel-3694 should always have the index buffer[3693]. I want to be able to see the two peaks on the horizontal edges of the plot, and the real measurement in-between.
-
\$\begingroup\$ For ... next loop "waste" time (ok, depending on the compiler). I should replace it with a conditional instruction, more regular, DMA transfer if possible. \$\endgroup\$Antonio51– Antonio512022年12月01日 15:53:17 +00:00Commented Dec 1, 2022 at 15:53
-
\$\begingroup\$ @Antonio51 Thanks for the quick response. I tried with DMA (following some person's tutorial) but the problem with that was inconsistency of value index. As you can see from the last image, there are two dummy pixels which appear as 'peaks' when we visualize the sensor data. The problem is, sometimes the peaks were next to each other, sometimes only one peak, sometimes no peak, sometimes both peaks in the center of frame, etc. It looked like the window keeps shifting after each iteration. I don't know how to fix that, so that's why I am trying without DMA. \$\endgroup\$Harit– Harit2022年12月01日 15:58:49 +00:00Commented Dec 1, 2022 at 15:58
-
\$\begingroup\$ @Antonio51 Here is the tutorial link: curiousscientist.tech/blog/tcd1304-linear-ccd-driving-the-ccd \$\endgroup\$Harit– Harit2022年12月01日 16:00:02 +00:00Commented Dec 1, 2022 at 16:00
-
1\$\begingroup\$ Ok. I just found this digikey.be/en/maker/projects/… NB: the dummy outputs are not 32...+...14? \$\endgroup\$Antonio51– Antonio512022年12月01日 16:04:37 +00:00Commented Dec 1, 2022 at 16:04
-
\$\begingroup\$ @Antonio51 Yes you're right. I meant to write 'two blocks of dummy pixels'. One block is 32 pixels wide, the other is 14 pixels wide. Thanks for the link as well. I will go through it and practice some more. \$\endgroup\$Harit– Harit2022年12月02日 10:46:06 +00:00Commented Dec 2, 2022 at 10:46
1 Answer 1
I figured out what was wrong. I was taking measurements from the ADC via DMA (which is very fast) but I was transmitting the buffer via UART in blocking mode, which was too slow to keep up with the DMA. So, I configured another DMA stream from Memory to Peripheral (Memory to USART_TX). I am now able to receive the sensor data in the desired format.
Thanks to Antonio51 for pointing me in the right direction!
Explore related questions
See similar questions with these tags.