Line: 1 to 1 | ||||||||
---|---|---|---|---|---|---|---|---|
TCS3200 Color SensorIntroduction | ||||||||
Line: 71 to 71 | ||||||||
Towards reading the frequency of the OUT signal | ||||||||
Changed: | ||||||||
< < | In order to better understand the TCS3200 it is necessary to get a feeling for the frequencies it emits. In order to measure this frequency, we must be able to set the filter and the frequency divider. This is done in the program filter_and_freq.py. The test program sets debugging mode, and it writes and reads back the filter and frequency divider settings. | |||||||
> > | In order to better understand the TCS3200 it is necessary to get a feeling for the frequencies it emits. To measure this frequency, we must be able to set the filter and the frequency divider. This is done in the program filter_and_freq.py. The test program sets debugging mode, and it writes and reads back the filter and frequency divider settings.
Reading the raw signalThe outSignal.py application sets up the filter to clear and the frequency divider to 2%. After this, it reads out the raw signal with the method testOut. This method sets up an empty data list named values, and it then polls the OUT line during 100 ms at a sampling frequency of 10 kHz (a sample every 100 us). The data acquired are saved in values and returned by the testOut method. outSignal finally prints out the result. The testOut method has been implemented for test only and is not strictly necessary. However, it gives a visual impression of the signal to be treated and is therefore interesting for a better understanding. You can save these values to a file on the PC with ampy run outSignal.py > resultData.txt and finally, plot the with gnuplot. Here are the plots when a black and when a white paper is placed in front of the sensor. You clearly see the much higher output frequency for a white paper. The black paper: The white paper | |||||||
Measuring the frequencyIn order to measure the frequency, the time elapsed for the detection of a number of OUT signal cycles is measured. The number of cycles to be used is set in the cycles variable. Of course, we again need getter and setter methods to control _cycles. We attach an interrupt handler to the OUT pin (_cbfwhich stands for _callback function). The number of cycles, already measured, is saved in the _cycle (without the "s"). This value is set to zero when the interrupt handler is started (connected to _cbf). When the first rising edge of the signal is seen, the current system clock in us is saved in _start_tick. For each rising edge of the OUT signal, _cycle is incremented until the value In _cycles is reached, in which case the system clock is saved in _end_tick. The duration between the start of the measurement and the moment the number of requested cycles has been seen is then | ||||||||
Line: 134 to 152 | ||||||||
| ||||||||
Added: | ||||||||
> > |
|
Line: 1 to 1 | |||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
TCS3200 Color SensorIntroduction | |||||||||||||||||||||||||||||||
Line: 32 to 32 | |||||||||||||||||||||||||||||||
This means that with a setting of 2% the frequency is divided by a factor 50. The LED control line allows switching the illumination LEDs on and off. | |||||||||||||||||||||||||||||||
Added: | |||||||||||||||||||||||||||||||
> > | CablingThe following table shows the cabling of the TCS3200 (the model on the left photo)
| ||||||||||||||||||||||||||||||
Understanding the module and developing a driver for itThe software is available on github: https://github.com/uraich/TCS3200-MicroPython |
Line: 1 to 1 | ||||||||
---|---|---|---|---|---|---|---|---|
TCS3200 Color SensorIntroduction | ||||||||
Line: 98 to 97 | ||||||||
This means that we must measure the frequencies of each color component for a black and a white target. This is done in calibration.py.
Detecting colors | ||||||||
Changed: | ||||||||
< < | -- Uli Raich - 2022-05-16 | |||||||
> > | Once the calibration is done, we have all the tools needed to measure rgb values. We must use the methods that were used to measure the frequencies for black and white targets for the measurement of colored targets. The rgb values are calculated with the formula shown in the calibration section.
In order to check the validity of the measurements, we can display the rgb values on the WS2812 LED ring. The rgb.py test program does exactly this. Place a colored target in front of the TCS3200 and the same color will be displayed on the WS2812 LED ring.
The driverFinally, the application can be separated from the driver part and stored in a file named tcs3200.py. This file must be copied to the ESP32 (I use its lib directory). from tcs3200 import TCS3200 imports the class with all its methods and its class variables. Now we can re-write all our test programs as short applications, making use of the driver. This essentially means to just copy the main part of the test programs into separate files. You find the driver on the github repository in the folder name driver. | |||||||
Comments |
Line: 1 to 1 | ||||||||
---|---|---|---|---|---|---|---|---|
TCS3200 Color SensorIntroduction | ||||||||
Line: 83 to 83 | ||||||||
time.sleep_ms(10) will wait forever, if the number of cycles to be measured, is never reached. This can happen e.g. if the OUT signal is assigned a wrong GPIO pin. The problem can be solved by starting a timeout counter when the measurement is started. This counter can be used to raise an exception if reaching the _cycles limit takes too long. | ||||||||
Added: | ||||||||
> > | timeout.py is the same program as meas_freq.py with the timeout counter added. The timeout is set to 2s. The number of cycles to be measured is set to 10000 in order to provoke the timeout. | |||||||
Calibration | ||||||||
Added: | ||||||||
> > | The formula for the calculation of rgb values is given by:
component = max * (Fv - Fb) / (Fw - Fb) where the variables have the following meaning:
Detecting colors | |||||||
-- Uli Raich - 2022-05-16
Comments |
Line: 1 to 1 | ||||||||
---|---|---|---|---|---|---|---|---|
TCS3200 Color SensorIntroduction | ||||||||
Line: 58 to 58 | ||||||||
Towards reading the frequency of the OUT signalIn order to better understand the TCS3200 it is necessary to get a feeling for the frequencies it emits. In order to measure this frequency, we must be able to set the filter and the frequency divider. This is done in the program filter_and_freq.py. The test program sets debugging mode, and it writes and reads back the filter and frequency divider settings. | ||||||||
Changed: | ||||||||
< < | Measuring the frequency | |||||||
> > | Measuring the frequency | |||||||
Changed: | ||||||||
< < | In order to measure the frequency, the time elapsed for the detection of a number of OUT signal cycles is measured. The number of cycles to be used is set in the _cycles variable. Of course, we again need getter and setter methods to control _cycles. We attach an interrupt handler to the OUT pin (_cbf for callback function). The number of cycles, already measured, is saved in the _cycle (without the "s"). This value is set to zero when the interrupt handler is started (connected to _cbf). When the first rising edge of the signal is seen, the current system clock in us is saved in _start_tick. For each rising edge of the OUT signal, _cycle is incremented until the value In _cycles is reached, in which case the system clock is saved in _end_tick. The duration between the start of the measurement and the moment the number of requested cycles has been seen is then | |||||||
> > | In order to measure the frequency, the time elapsed for the detection of a number of OUT signal cycles is measured. The number of cycles to be used is set in the cycles variable. Of course, we again need getter and setter methods to control _cycles. We attach an interrupt handler to the OUT pin (_cbfwhich stands for _callback function). The number of cycles, already measured, is saved in the _cycle (without the "s"). This value is set to zero when the interrupt handler is started (connected to _cbf). When the first rising edge of the signal is seen, the current system clock in us is saved in _start_tick. For each rising edge of the OUT signal, _cycle is incremented until the value In _cycles is reached, in which case the system clock is saved in _end_tick. The duration between the start of the measurement and the moment the number of requested cycles has been seen is then | |||||||
duration =_end_tick - _start_tick | ||||||||
Line: 75 to 75 | ||||||||
This teaches us an important lesson: The time between two rising edges for the white target is just 435 us. If we change the frequency divider to 20% this time would be reduced to 43 us, which is simply too short an interval for our interrupt handler. The program can handle a 20% frequency divider setting for the black target, in which case the interval is 263 us (1000000/3800), but it will crash for the white target because it will receive new interrupts while the old ones have not been entirely treated. If we want to read the OUT signal at full speed, then an external high speed counter is needed. Otherwise, we can fix the S0 and S1 signals to 0 and 1 respectively and therefore fix the frequency divider to 2%. This liberates 2 GPIO lines for other purposes. | ||||||||
Added: | ||||||||
> > | Timeouts | |||||||
There is still a problem with the meas_freq.py program. The code: | ||||||||
Added: | ||||||||
> > | ||||||||
while tcs3200._end_tick == 0: time.sleep_ms(10)will wait forever, if the number of cycles to be measured, is never reached. This can happen e.g. if the OUT signal is assigned a wrong GPIO pin. The problem can be solved by starting a timeout counter when the measurement is started. This counter can be used to raise an exception if reaching the _cycles limit takes too long. | ||||||||
Changed: | ||||||||
< < | Calibration | |||||||
> > | Calibration | |||||||
-- Uli Raich - 2022-05-16
Comments |
Line: 1 to 1 | ||||||||
---|---|---|---|---|---|---|---|---|
TCS3200 Color SensorIntroduction | ||||||||
Line: 76 to 76 | ||||||||
If we want to read the OUT signal at full speed, then an external high speed counter is needed. Otherwise, we can fix the S0 and S1 signals to 0 and 1 respectively and therefore fix the frequency divider to 2%. This liberates 2 GPIO lines for other purposes. | ||||||||
Added: | ||||||||
> > | There is still a problem with the meas_freq.py program. The code: while tcs3200._end_tick == 0: time.sleep_ms(10)will wait forever, if the number of cycles to be measured, is never reached. This can happen e.g. if the OUT signal is assigned a wrong GPIO pin. The problem can be solved by starting a timeout counter when the measurement is started. This counter can be used to raise an exception if reaching the _cycles limit takes too long. Calibration | |||||||
-- Uli Raich - 2022-05-16
Comments |
Line: 1 to 1 | ||||||||
---|---|---|---|---|---|---|---|---|
TCS3200 Color SensorIntroduction | ||||||||
Line: 6 to 6 | ||||||||
The TCS3200 color sensor comes on PCBs with slightly different layout:
| ||||||||
Changed: | ||||||||
< < | The main difference between the modules is that one of them pulls out the TCS3200 OE (Output Enable) line, while the other does not. | |||||||
> > | The main difference between these modules is that one of them pulls out the TCS3200 OE (Output Enable) line, while the other one does not. | |||||||
Changed: | ||||||||
< < | The TCS3200 uses an array of 64 photo cells, where 16 of the cells are equipped with a red, green or blue filter while the remaining 16 cells have no filter at all. | |||||||
> > | The TCS3200 uses an array of 64 photo cells, where 16 of the cells are equipped with a red, green or blue filter respectively, while the remaining 16 cells have no filter at all. | |||||||
Line: 34 to 34 | ||||||||
The LED control line allows switching the illumination LEDs on and off.
Understanding the module and developing a driver for it | ||||||||
Changed: | ||||||||
< < | The software is available on github: | |||||||
> > | The software is available on github: https://github.com/uraich/TCS3200-MicroPython | |||||||
First steps | ||||||||
Changed: | ||||||||
< < | A driver in MicroPython is usually implemented as a Python class. The object creation method init initializes the chip. In case of the TCS3200, the GPIO lines used to control | |||||||
> > | A driver in MicroPython is usually implemented as a Python class. The object creation method __init__ initializes the chip. In case of the TCS3200, the GPIO lines used to control | |||||||
| ||||||||
Changed: | ||||||||
< < | To have a first preliminary check, we can implement, kin addition to the init method, a method that switches the LEDs on and off. I prefer to also have a debug method allowing me to switch debugging messages on and off. | |||||||
> > | To have a first preliminary check, we can implement, kin addition to the __init__ method, a method that switches the LEDs on and off. I prefer to also have a debug method allowing me to switch debugging messages on and off. | |||||||
Changed: | ||||||||
< < | This is implemented in the led.py program. To ease development, the driver and the application using it, are combined in the same file. Once the driver is sufficiently tested, these two parts will be separated in two distinct files. The driver will be uploaded to the /lib folder on the ESP32 to make it permanently accessible. | |||||||
> > | This is implemented in the led.py program. Another short MicroPython program: switchOffLeds.py is provided to switch the LEDs off. This can be run on the ESP32 from the command line using the shell script switchOffLeds. Make sure that execute permission is given for the script. To ease development, the driver and the application using it, are combined in the same file. Once the driver is sufficiently tested, these two parts will be separated in two distinct files. The driver will be uploaded to the /lib folder on the ESP32 to make it permanently accessible. | |||||||
In Python there are no public and private variables. There is however a convention that variables whose names start with the '_' character to be considered private. | ||||||||
Line: 55 to 57 | ||||||||
Towards reading the frequency of the OUT signal | ||||||||
Changed: | ||||||||
< < | In order to better understand the TCS3200 it is necessary to get a feeling for the frequencies it emits. In order to measure this frequency, we must be able to set the filter and the frequency divider. This is done in the program filter_and_freq.py. The test program sets debugging mode, and it writes and reads back the filter and frequency divider settings. | |||||||
> > | In order to better understand the TCS3200 it is necessary to get a feeling for the frequencies it emits. In order to measure this frequency, we must be able to set the filter and the frequency divider. This is done in the program filter_and_freq.py. The test program sets debugging mode, and it writes and reads back the filter and frequency divider settings. | |||||||
Measuring the frequencyIn order to measure the frequency, the time elapsed for the detection of a number of OUT signal cycles is measured. The number of cycles to be used is set in the _cycles variable. Of course, we again need getter and setter methods to control _cycles. We attach an interrupt handler to the OUT pin (_cbf for callback function). The number of cycles, already measured, is saved in the _cycle (without the "s"). This value is set to zero when the interrupt handler is started (connected to _cbf). When the first rising edge of the signal is seen, the current system clock in us is saved in _start_tick. For each rising edge of the OUT signal, _cycle is incremented until the value In _cycles is reached, in which case the system clock is saved in _end_tick. The duration between the start of the measurement and the moment the number of requested cycles has been seen is then | ||||||||
Line: 64 to 66 | ||||||||
and the frequency in Hz is 1000000 * _cycles / duration. The factor 1000000 comes from the fact that the duration is measured in us while the frequency is calculated in Hz. | ||||||||
Added: | ||||||||
> > | This program is implemented in meas_freq.py. It shows that for clear filters, the frequency divider set to 2% and a white target, I measure a frequency of 2.349 kHz. When using a black target, the frequency drops to 380 Hz. This teaches us an important lesson: The time between two rising edges for the white target is just 435 us. If we change the frequency divider to 20% this time would be reduced to 43 us, which is simply too short an interval for our interrupt handler. The program can handle a 20% frequency divider setting for the black target, in which case the interval is 263 us (1000000/3800), but it will crash for the white target because it will receive new interrupts while the old ones have not been entirely treated. If we want to read the OUT signal at full speed, then an external high speed counter is needed. Otherwise, we can fix the S0 and S1 signals to 0 and 1 respectively and therefore fix the frequency divider to 2%. This liberates 2 GPIO lines for other purposes. | |||||||
-- Uli Raich - 2022-05-16
Comments | ||||||||
Line: 76 to 88 | ||||||||
| ||||||||
Added: | ||||||||
> > |
|
Line: 1 to 1 | |||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Added: | |||||||||||||||||||||||||||||||||||||||||||||||||
> > |
TCS3200 Color SensorIntroductionThe TCS3200 color sensor comes on PCBs with slightly different layout:
Understanding the module and developing a driver for itThe software is available on github:First stepsA driver in MicroPython is usually implemented as a Python class. The object creation method init initializes the chip. In case of the TCS3200, the GPIO lines used to control
Towards reading the frequency of the OUT signalIn order to better understand the TCS3200 it is necessary to get a feeling for the frequencies it emits. In order to measure this frequency, we must be able to set the filter and the frequency divider. This is done in the program filter_and_freq.py. The test program sets debugging mode, and it writes and reads back the filter and frequency divider settings.Measuring the frequencyIn order to measure the frequency, the time elapsed for the detection of a number of OUT signal cycles is measured. The number of cycles to be used is set in the _cycles variable. Of course, we again need getter and setter methods to control _cycles. We attach an interrupt handler to the OUT pin (_cbf for callback function). The number of cycles, already measured, is saved in the _cycle (without the "s"). This value is set to zero when the interrupt handler is started (connected to _cbf). When the first rising edge of the signal is seen, the current system clock in us is saved in _start_tick. For each rising edge of the OUT signal, _cycle is incremented until the value In _cycles is reached, in which case the system clock is saved in _end_tick. The duration between the start of the measurement and the moment the number of requested cycles has been seen is then duration =_end_tick - _start_tick and the frequency in Hz is 1000000 * _cycles / duration. The factor 1000000 comes from the fact that the duration is measured in us while the frequency is calculated in Hz. -- Uli Raich - 2022-05-16Comments
|