TCS230 output problem..Help plz
thava
Posts: 17
Hi guys, i have recently programmed my PIC 16f877a, im using TCS230 as my color sensor, so i have used interrupt function to read the output of TCS230 and send it to PC via rs232, below is the program i did,
, so if you look at the code, i have type 'S' from my pc to get the output from PIC, but what im getting is only (0,0,0) whereby when i measure the output of sensor directly to oscilloscope and there it output and kip changing when the filter changed by the PIC according to the software above, but when i measure the amplitude of the output, its 2.5 to 2.6V in output line of the sensor, is it the reason that PIC couldnt read it? do i need to amplify the signal for PIC? Hereby i attach the datasheet of TCS230. if i need to amplify, what it the best way? Op-Amp or Transistor?
#include <stdio.h> #include <htc.h> #include "usart.h" #include "delay.h" __CONFIG(0x3f71); #define NUMBER_OF_PERIODS 6 unsigned int average; unsigned char isAverageReady; int R, G, B; void delay ( void ) { DelayMs ( 100 ); } static interrupt void isr ( void ) { static unsigned int time [noparse][[/noparse] NUMBER_OF_PERIODS + 1 ]; static unsigned char timeIndex = 0; if ( INTF ) { time [noparse][[/noparse] timeIndex++ ] = ( TMR1H << 8 ) + TMR1L; if ( timeIndex == NUMBER_OF_PERIODS + 1 )// wait until period reach 5 then 5+1 and proceed { INTE = 0; timeIndex = 0; average = ( time [noparse][[/noparse] NUMBER_OF_PERIODS ] - time [noparse][[/noparse] 0 ] ) / NUMBER_OF_PERIODS; //time is a memory location, time [noparse][[/noparse]0] is start and number of period is end, end -start /end isAverageReady = 1; } INTF = 0; } } void getRGB ( void ) { // Get R Value RB2 = 0; RB4 = 0; delay(); isAverageReady = 0; INTE = 1; while ( !isAverageReady ) continue; R = average; // Get G Value RB2 = 1; RB4 = 1; delay(); isAverageReady = 0; INTE = 1; while ( !isAverageReady ) continue; G = average; // Get B Value RB2 = 0; RB4 = 1; delay(); isAverageReady = 0; INTE = 1; while ( !isAverageReady ) continue; B = average; } void main ( void ) { unsigned char input; // Initializations init_comms(); TRISB = 0x01; INTEDG = 0; INTE = 1; TMR1CS = 0; GIE = 1; while ( 1 ) { // Body input = getch(); switch ( input ) { case 'S': getRGB(); printf ( "%d,%d,%d\r\n", R, G, B ); break; } } }
, so if you look at the code, i have type 'S' from my pc to get the output from PIC, but what im getting is only (0,0,0) whereby when i measure the output of sensor directly to oscilloscope and there it output and kip changing when the filter changed by the PIC according to the software above, but when i measure the amplitude of the output, its 2.5 to 2.6V in output line of the sensor, is it the reason that PIC couldnt read it? do i need to amplify the signal for PIC? Hereby i attach the datasheet of TCS230. if i need to amplify, what it the best way? Op-Amp or Transistor?
pdf
116K
Comments
What voltage is the PIC running at? 3.3v or 5v?
I don't use the PIC, but is the line you are using configured as an input or output?
Did you enable the TCS230, so that it will give an output? I assume that is the case since you are seeing the output on the scope, but never be too careful, a scope has high input impedance...
The voltage you are talking about seems low to register as a 1 on a 5v device, but I don't remember the exact cut-over voltage. If you are running them from the same supply voltage, I would assume that they should just work.
How are you measuring the output of the TCS230, it converts light to frequency... Are you counting a pulse train?
Did you double check all connections, the low output voltage would be bothering me...
-Phil
How are you measuring the frequency the chip puts out? Are you counting pulses over a measure of time? Is that what you are using the interrupt for?
Well, as always, there are probably people who know way more than me, but this is how I understand things:
I expect there are various advantages related to outputting a frequency over other methods, although I find it hard to imagine anything easier than a straight binary answer.
In the real world everything is analog and constantly varying, you cannot really represent an analog value *perfectly* using a digital number, there will always be some error, although the most important criteria is probably whether or not the error is material to what you are doing.
Reasons I can think of for using frequency output:
* By using a frequency output, you are translating the original value to something that can be measured more easily (compared to other options) by a microprocessor with accuracy, since microprocessors need relatively accurate timebases anyway.
* You reduce the problems of noise, since in this case anyway, it outputs a square wave, so unlike a voltage, there is less noise to worry about between the measuring device and the microprocessor..
* Keeping in mind that when you convert the input value to frequency rather than a digital value, you are keeping the value in the analog domain longer, but converting it to a signal that is easier to use with a microprocessor; by using a frequency you can decide for yourself how accurate the answer needs to be, if the chip outputs a number of binary bits, it is all the resolution you can hope to have. Maybe it will be too much, maybe too little. with a frequency YOU can decide for yourself how accurately you want to measure the frequency.
* I could be wrong, but I think it is cheaper and simpler to measure frequency than voltage with a microprocessor, and possibly faster for the same resolution.
So on to errors:
You have the error that the conversion from light to frequency introduces, you have decided on your chip, so other than being careful about the power to the chip and the ambient temperature, I'm not sure there is a lot you can do...
In terms of the measurement in your microprocessor I can see these things contributing to error:
* The clock frequency of the microprocessor needs to be stable, any error here will influence your measurement.
* You need to balance measurement speed vs averaging the measurement errors. So getting a faster answer will cost you accuracy, if you count the frequency for a longer time, you will generally get a more accurate answer.
* How do you know how much time has passed?, are you using a system clock counter like the propeller has? I have to say, the Parallax propeller is so perfect for this, it not only has onboard counters to measure the pulses without programming intervention, but it also lets you know exactly how many clock ticks have passed since you last took a reading. Plus, no interrupts, making everything simpler. You can make accurate measurements with the propeller almost effortlessly in this situation. There are frequency counting examples provided by Parallax as well.
I am assuming that your code uses each pulse from the colour chip to interrupt the processor, recording another pulse, and that you are using some sort of timing loop to create delays.
In your code, you need to make sure that your timing loop is deterministic and you probably need to know the exact timing (so you can measure how many pulses per accurate time period), although someone clever might be able to make that not matter.
Not to push the propeller on you, but you would not need to use assembler to accomplish this with the propeller, because of being able to read the system clock or wait until a certain exact time has passed. However, the propeller has been designed to have deterministic loop timing.
Unless you can read an independent counter based on your clock ticks or have a way to create accurate delays, you will probably need to adjust for the time that interrupt handling takes out of your timing loop. I assume that is deterministic, but it may not be.
Does that help at all?
Rick, actually my sensor was working well, but the output, when i measured it in oscilloscope, its not stable, like an example.
i triggered to blue filter and measured a blue printed A4 paper, so during my measurement in oscilloscope, it varies greatly, it alternates crazily, like 3,98khz to 4.59khz and then back to 3.8khz, and go back to 4.83 khz, and return back to 3.39 khz, it just keeps alternating. so what i did was, i concluded that external light source is giving too much of trouble and i get a black box, stick it on my PCB all around the white LED and also the sensor, its covering around, the sensor is covered by 1.7cm plastic around it. So when now i measure it, the waveform actually got worst, it varies like hell and there is noise in the waveform now. its getting crazy. i really got no idea what to do.
my circuitry is like very simple, a color sensor and two white bright led by the side of it, i just design it by myself, do anyone can give me idea what would be the problem, please someone, and is there certain specification how the LED must be fixed by the side of sensor? please someone help me. cause once the sensor is stable only, i could do my pixel level analysis and sensitivity analysis.
Did you tie all pins to something on the chip? Particularly S0 and S1 (pins 1 and 2) they change the output scaling, which would certainly affect your frequency.
Is the sensor signal stable when it cannot see anything at all?
Is the sensor signal stable when it views a stable light source? Like say one LED?
Try turning off the overhead lights.
I would try a non-led light source. Like a flashlight with an incandescent bulb.
Is the paper moving when you are measuring it?
I would also check the voltage going to the LEDs to make sure it is stable (with the scope).
I would check the voltage going to your sensor with the scope.
Do you need decoupling capacitors?
Post Edited (Rick Price) : 5/22/2009 1:34:06 PM GMT
That was not written as clearly as it could have been, I was busy and getting interrupted constantly that day. I can write it again with more organization and clarity for you if you need me to.
and the bitrate as well, is there anywhere i could measure it? and thanks a lot for your concern. concerning to TCS230db, do they sell em in one piece or minimum 5? thank you.
The information provided by Parallax information in that document is really good, you should make a point of reading it carefully.
As to the output frequency, if you look on page 3 of the document you have attached to this thread, it gives the maximums expected (Full-scale frequency). It does not really seem to list the minimum frequency you can expect for a *black* condition, but you should be able measure the device you have to get an idea. In a production unit, I would expect that you could turn off the lighting LEDs and measure the base frequency. Keeping in mind that it seems to change based on which colour you are selecting. You probably need to calibrate each colour separately. There seems to be three ranges of frequencies that can be selected, the slower frequencies are based on _sampling_ the maximum clock (I believe), therefore it is better to use the fastest frequency if you are concerned with accuracy.
The resolution of the sensor would then be the maximum (full light or perfect reflection) frequency - the minimum (black) frequency. If I was calibrating it, I would start by putting a perfect reflector in front of the sensor so all the light would get to it and measure the frequency, selecting each colour in turn, then I would turn off the light and measure the frequency for each colour in turn, waiting an appropriate amount of time for settling. That would give you the range of the sensor.
When taking a measurement I would take the observed frequency and subtract the black frequency from it, I would then divide by the range. You would need to scale that to whatever range of values you were using.
The range from full white to full black is the maximum resolution you can get, when you take that and convert it to a number say 12 bits or 8 bits or whatever, you will introduce error, I believe you calculate how much error by figuring out the number of bits in the actual range compared to the range that you convert it down to. If you have a wide bus, then you could possibly just use the values in raw form, but it would depend on your application.
You really need to determine your application before you worry about resolution or error because it will affect what is acceptable.
You should also read the parallax document because it explains how the device responds to light, it does not respond equally to each wavelength of light, so you will need to correct the measured values if you want a linear response. I'm not sure how others would do the conversion, but you could use a lookup table, or possibly a simple mathematical function depending on your required accuracy.
Can you tell me what you are going to use the sensor for? That would really help determine how much accuracy and error you need to worry about.
Accuracy and linearity can be big complicated topics, it would help to know how much you really need, it makes it much easier to pare down what needs to be discussed and WHO should be discussing it, since I am not experienced in this area.
The things you need to answer are:
* How quickly does it need to take a reading
* How linear do the measurements need to be? Are we just comparing the CHANGE of a reading, or are we looking for an absolute standard.
* How many bits of resolution are required for whatever the output will be used for
* How much inaccuracy is acceptable, accuracy is costly, you don't want to specify more than is really needed.
As to bitrate, I'm not sure that I understand the question, bitrate in terms of information content, does not seem to be the correct question here. However, the best *information* you can get from the sensor, is the range of values it will put out from full light to full black divided by how fast you can reliably take a reading. That would be the maximum bitrate as I understand it.
If you mean, how fast can I take measurements, it will depend on how fast you can measure the frequency and some internal limitations of the chip, they mention the required parameters for the chip in the docs we have at hand. But I think you need to determine what you need before you worry about what it can do. There is no point in hurting yourself trying to maximize something that it is an order of magnitude faster than you need without doing anything.
I will try to edit my original post about measuring frequency for clarity and organization soon.
come to application. ok now its for my final project, im using TCS230 to sense color from a medium, say from A4 paper, then measure the reading with PIC and transmit to PC via rs232, then there will be a visual c++ interface which plots out exact colors been captured by TCS230, the title of the project is Image Processing using CMOS color sensor.
so help me to clarify the real needs that i need to know from this sensor according to my application. sorry for bothering you, but im trying to cut cost by developing TCS230 by my own and get some technical knowledge as well, so please help me mate. my first analysis on this sensor was without LED illumination and get the base reading, i did that already, and i got almost linear graph from it, and then fixed my own LED, white bright LED and measured and got linearity as well, but the output is bigger compare to earlier analysis, because when the board has no its own illumination, when take reading, the paper shaded by the sensor, so its not the proper method, then after fixing LED, its better.
the difference is like this, when i measure without LED, when the sensor gets near to the surface the output frequency decrease until in Hz, then with LED, the output increases when goes near, like in kHz, then to make the output more stable, i fixed a black box around it, but it turn out to be im getting noise at the output. this is the update currently im getting.
So your current concern is the instability in the frequency?
I would then try to find what is causing the variation...
What you want to do ideally is halve the places where the problem is coming in, until you can simply see what the problem is.
I would check (using a scope):
* Your scope (use the calibration output or a _known_ good frequency, the last might be better.
* Your scope triggering (for completeness maybe it is making things seem like they are changing when they are not)
* The sensor with a very smooth light, try a flashlight. See if the output is stable.
* Ensure all overhead lighting is off, remember it will pulse at 50hz or 60hz at least.
* Does the sensor need a lens? Maybe it needs one to work correctly
* If things are stable without your LEDs, add them to the situation.
* If they seem to be a problem, switch to using a constant current source for them.
* Ensure the paper is not moving, maybe the detector is very sensitive
* Look for noise on your power supply lines
* Make sure you are using proper bypass capacitors
I don't know how stable you can expect the output to be, it IS analog and therefore not static like binary. But it would seem reasonable for things to vary less than 10% for sure, and probably more like 1% of the output frequency, quite possibly much less. Can you get an exact measurement of the variation with a stable light source?
If you look at how the Parallax board does it, the LED shines on the paper which reflects is back to the sensor, is that how you have it setup?
* In a production device I would use the full scale frequency setting from the sensor, however, in your application you might want to use the first step reduction frequency (the smallest divide by). The advantage of this will be that the frequency output should be more stable, and you will get less interrupts on your PIC. You may need to reduce the frequency even more, since you might get a rather large amount of interrupts and I expect that will cause trouble given how you have designed the overall architecture (counting using an interrupt). I'm not saying you did something wrong, but every choice has a side-effect.
* Because the *black* frequency is so low, we probably cannot use it directly. What might be better would be to put a black piece of paper under the sensor and read the frequency you get from that with the LEDs on. Record that frequency in a log book, and of course do it for each colour. You can use that for your *black* level for each colour.
* Record the frequency for each colour using a piece of very white paper, and record the frequencies.
* Find the maximum range of frequencies from all three colours, this will give you an idea of how large a variable to use to store the values.
* I would use the difference between the black light level and the reading light level as the value I send back to the PC.
My concern with your using an interrupt to count the pulses are as follows:
Very high frequencies will cause very high interrupt rates, in a production system, this would probably be very undesirable. Interrupts keep the microprocessor from doing something else, and they *can* be expensive in clock cycles. Because you are AFAIK using a timing loop in your code (rather than a timebase of some sort), I have concerns about the interrupts interfering with your timing. Basically the more interrupts you have, the more time lost inside of the interrupt handler, unless your timing loop takes that into account, the time spent in the loop will change based on the frequency (because the interrupt is stealing CPU cycles from it). You also need to worry about whether your CPU can handle interrupts at the frequencies you are getting from the sensor. Using the internal divider in the sensor could help of course, but you will lose resolution.
You should really check to see if your PIC has some sort of counter that is incremented by your system clock, it will really improve the accuracy of your readings because it will not be affected by your interrupts.
I don't know the PIC architecture, but I think a propeller chip would be perfect in this situation for these reasons, if the PIC also has some of these capabilities I think you should consider using them.
* The propeller has a built in counter that increases with the clock frequency. This allows you to very easily measure time.
* To create accurate timing loops, you use that counter with a special wait instruction that waits for a given number of clock cycles.
* The propeller has built in counters, this allows you to very easily measure frequency counts.
* By putting the two together, you can make easy and accurate frequency measurements; what you are trying to do with your design.
* While this may not be an advantage in school, the propeller has libraries for doing most common (and not so common) embedded tasks, all of it BSD Open Source. You could implement a frequency counter and serial communication in about an hour (possibly less) if you were familiar with the tools by just using libraries. Setting the outputs to communicate with the sensor might take a few more minutes. The propeller is a very high productivity tool IMO.
Parallax has a demo program for the Stamp BS2pe called ColorDemo12. This program contains the code for the white reference. It calculates the periods required for each color to produce a value of 255 for a white reference target. It should be relatively easy to convert to C