{"id":343,"date":"2013-02-11T16:55:04","date_gmt":"2013-02-12T00:55:04","guid":{"rendered":"http:\/\/micromouseusa.com\/?p=343"},"modified":"2013-02-11T17:27:02","modified_gmt":"2013-02-12T01:27:02","slug":"a-easier-way-to-ir-sensor-pulse-control","status":"publish","type":"post","link":"http:\/\/micromouseusa.com\/?p=343","title":{"rendered":"a easier way to use pulse control for IR sensor"},"content":{"rendered":"<p>Since pulse controlled are getting pretty popular these days, emitter need to be turned on with a current higher than forward current at a relatively short time period. Usually, the turn on time is under 100us in order to make receiver receive sufficient reflection light. Some people like Ng Beng Kiat use an additional timer to trigger DMA associated with NVIC to scan ADC between different channels, the whole process is relatively complicate than only using ADC to receiver sensor signal without using Direct Memory Access(DMA).<\/p>\n<p>I used a different way in order to simplify the process by utilizing the tracked system time in micro second, here is the sample code<\/p>\n<p><span style=\"color: #ffff00;\">\/********* adc1 setup **********\/<\/span><\/p>\n<p><span style=\"color: #ffff00;\">\/\/call this function in int main() to initialized ADC<\/span><\/p>\n<p><span style=\"color: #ffff00;\">void adcConfig(void)<\/span><\/p>\n<p><span style=\"color: #ffff00;\">{<\/span><\/p>\n<p><span style=\"color: #ffff00;\">ADC_InitTypeDef ADC_InitStructure;<\/span><br \/>\n<span style=\"color: #ffff00;\"> RCC_ADCCLKConfig(RCC_PCLK2_Div6);\/\/ADC works at 72\/6=12MHz<\/span><br \/>\n<span style=\"color: #ffff00;\"> \/\/*\u00a0\u00a0\u00a0\u00a0 ADC1 Configuration\u00a0\u00a0 \u00a0\u00a0\u00a0 *<\/span><br \/>\n<span style=\"color: #ffff00;\"> ADC_DeInit(ADC1);<\/span><br \/>\n<span style=\"color: #ffff00;\"> ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;<\/span><br \/>\n<span style=\"color: #ffff00;\"> ADC_InitStructure.ADC_ScanConvMode = DISABLE;<\/span><br \/>\n<span style=\"color: #ffff00;\"> ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;<\/span><br \/>\n<span style=\"color: #ffff00;\"> ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;<\/span><br \/>\n<span style=\"color: #ffff00;\"> ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;<\/span><br \/>\n<span style=\"color: #ffff00;\"> ADC_InitStructure.ADC_NbrOfChannel = 1;<\/span><br \/>\n<span style=\"color: #ffff00;\"> ADC_Init(ADC1, &amp;ADC_InitStructure);<\/span><br \/>\n<span style=\"color: #ffff00;\"> ADC_Cmd(ADC1, ENABLE);<\/span><br \/>\n<span style=\"color: #ffff00;\"> ADC_ResetCalibration(ADC1);<\/span><br \/>\n<span style=\"color: #ffff00;\"> while (ADC_GetResetCalibrationStatus(ADC1))<\/span><br \/>\n<span style=\"color: #ffff00;\"> ADC_StartCalibration(ADC1);<\/span><br \/>\n<span style=\"color: #ffff00;\"> while(ADC_GetCalibrationStatus(ADC1));<\/span><\/p>\n<p><span style=\"color: #ffff00;\">}<\/span><\/p>\n<p>whenever I need to read ADC data, I call this function as follow to get ADC value in 12 bits resolution by taking 28.5cycles equivalent time.<\/p>\n<p><span style=\"color: #ff9900;\">u16 readADC(ADC_TypeDef* ADCx, u8 channel)<\/span><br \/>\n<span style=\"color: #ff9900;\"> {<\/span><br \/>\n<span style=\"color: #ff9900;\"> ADC_RegularChannelConfig(ADCx, channel, 1, ADC_SampleTime_28Cycles5);<\/span><br \/>\n<span style=\"color: #ff9900;\"> ADC_SoftwareStartConvCmd(ADCx, ENABLE);<\/span><br \/>\n<span style=\"color: #ff9900;\"> while(ADC_GetFlagStatus(ADCx, ADC_FLAG_EOC) == RESET);<\/span><br \/>\n<span style=\"color: #ff9900;\"> return ADC_GetConversionValue(ADCx);<\/span><br \/>\n<span style=\"color: #ff9900;\"> }<\/span><\/p>\n<p>now is the process about how I use pulse control to read IR sensors. Here is the sensor configuration that I used for one of my mice with 4 sensors. left and right sensors emitters are serial to each other; left front and right front emitters are controlled individually.<\/p>\n<p>Since I serial a very low value resistor with emitter in order to make instant current higher than 100mah forward current, I have to turn on emitter for a pretty short time to prevent it burns out before receiver can start to ADC converting. However the advantage for pulse control sensors are also obvious: you will be able to send a very high signal from emitter to significant against ambient light, and your reading range will also be increased.<\/p>\n<p><a href=\"http:\/\/micromouseusa.com\/wp-content\/uploads\/2013\/02\/emitter.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-full wp-image-360\" alt=\"emitter\" src=\"http:\/\/micromouseusa.com\/wp-content\/uploads\/2013\/02\/emitter.jpg\" width=\"847\" height=\"543\" srcset=\"http:\/\/micromouseusa.com\/wp-content\/uploads\/2013\/02\/emitter.jpg 847w, http:\/\/micromouseusa.com\/wp-content\/uploads\/2013\/02\/emitter-300x192.jpg 300w, http:\/\/micromouseusa.com\/wp-content\/uploads\/2013\/02\/emitter-467x300.jpg 467w\" sizes=\"(max-width: 847px) 100vw, 847px\" \/><\/a> emitter system<a href=\"http:\/\/micromouseusa.com\/wp-content\/uploads\/2013\/02\/receiver.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-full wp-image-361\" alt=\"receiver\" src=\"http:\/\/micromouseusa.com\/wp-content\/uploads\/2013\/02\/receiver.jpg\" width=\"609\" height=\"549\" srcset=\"http:\/\/micromouseusa.com\/wp-content\/uploads\/2013\/02\/receiver.jpg 609w, http:\/\/micromouseusa.com\/wp-content\/uploads\/2013\/02\/receiver-300x270.jpg 300w, http:\/\/micromouseusa.com\/wp-content\/uploads\/2013\/02\/receiver-332x300.jpg 332w\" sizes=\"(max-width: 609px) 100vw, 609px\" \/><\/a><\/p>\n<p>receiver system<\/p>\n<p>Here is what I proffered for my pulse control process:<\/p>\n<p>For the emitter I use, SFH4545, I usually prefer to turn on emitter for 60-80us, then do ADC converting for the corresponding receiver, then turn off that emitter, wait for 80us until the infrared light from this emitter is totally disappeared to make sure rest of the receivers won\u2019t get any light from this emitter. After that, I just repeat the process again for next sensor.<\/p>\n<p>Here is my code<\/p>\n<p><span style=\"color: #ffff00;\">Void readSensor(void)<\/span><\/p>\n<p><span style=\"color: #ffff00;\">{<\/span><\/p>\n<p><span style=\"color: #ffff00;\">int curt = micros();\/\/record the current time<\/span><\/p>\n<p><span style=\"color: #ffff00;\">LF_EMITTER_ON;\/\/this is not sudo code, this is macro I defined somewhere else<\/span><\/p>\n<p><span style=\"color: #ffff00;\">While((micros()-curt)&lt;60);\/\/use up time until 60us from where we record curt<\/span><\/p>\n<p><span style=\"color: #ffff00;\">LFSensor =readADC(ADC1, 7)\/\/PA7 ADC1_IN7<\/span><\/p>\n<p><span style=\"color: #ffff00;\">LF_EMITTER_OFF;\/\/turn off emitter right after receiver done ADC converting<\/span><\/p>\n<p><span style=\"color: #ffff00;\">\/\/do linear regression here for left front sensor if you plan to linearize your sensor<\/span><\/p>\n<p><span style=\"color: #ffff00;\">While((micros()-curt)&lt;140);\/\/140-60=80us,wait 80us until reflection is gone<\/span><\/p>\n<p><span style=\"color: #ffff00;\">RF_EMITTER_ON;<\/span><\/p>\n<p><span style=\"color: #ffff00;\">While((micros()-curt)&lt;200);\/\/200-140=60us, turn on emitter for 60us<\/span><\/p>\n<p><span style=\"color: #ffff00;\">RFSensor=readADC(ADC1, 3);\/\/PA3 ADC1_IN3<\/span><\/p>\n<p><span style=\"color: #ffff00;\">RF_EMITTER_OFF;<\/span><\/p>\n<p><span style=\"color: #ffff00;\">\/\/do linear regression here for right front sensor if you plan to linearize your sensor<\/span><\/p>\n<p><span style=\"color: #ffff00;\">While((micros()-curt)&lt;280);\/\/280-200=80us<\/span><\/p>\n<p><span style=\"color: #ffff00;\">SIDE_EMITTER_ON;\/\/turn on side emitters for side sensors<\/span><\/p>\n<p><span style=\"color: #ffff00;\">While((micros()-curt)&lt;340);\/\/340-280=60us<\/span><\/p>\n<p><span style=\"color: #ffff00;\">leftSensor \u00a0= readADC(ADC1, 5); \/\/PA5 ADC1_IN5<\/span><\/p>\n<p><span style=\"color: #ffff00;\">rightSensor = readADC(ADC1, 4); \/\/PA4 ADC1_IN4<\/span><\/p>\n<p><span style=\"color: #ffff00;\">SIDE_EMITTER_OFF;<\/span><\/p>\n<p><span style=\"color: #ffff00;\">\/\/do linear regression here for side sensors if you plan to linearize your sensors<\/span><\/p>\n<p><span style=\"color: #ffff00;\">}<\/span><\/p>\n<p>Thus you have all your sensors easily read with pulse control. The process is much easier than using DMA triggered by timer, even though DMA does make it slightly faster for converting. In this process, my case spent about 340us with 4 sensors, and it will take 480us on my 6 sensors micromouse, after all, there is still 520-640us left for you to something else for you interrupt service routing if you sample every 1 ms. On other hand, your power consumption is fairly low since you don\u2019t turn on your emitter all the time, you can also turn off all your emitter before this process to let all receiver to pick up environmental light then subtract from it later when emitters are on in order to reduce noise.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Since pulse controlled are getting pretty popular these days, emitter need to be turned on with a current higher than forward current at a relatively short time period. Usually, the turn on time is under 100us in order to make &hellip; <a href=\"http:\/\/micromouseusa.com\/?p=343\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_links_to":"","_links_to_target":""},"categories":[7],"tags":[],"jetpack_featured_media_url":"","_links":{"self":[{"href":"http:\/\/micromouseusa.com\/index.php?rest_route=\/wp\/v2\/posts\/343"}],"collection":[{"href":"http:\/\/micromouseusa.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/micromouseusa.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/micromouseusa.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/micromouseusa.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=343"}],"version-history":[{"count":10,"href":"http:\/\/micromouseusa.com\/index.php?rest_route=\/wp\/v2\/posts\/343\/revisions"}],"predecessor-version":[{"id":1232,"href":"http:\/\/micromouseusa.com\/index.php?rest_route=\/wp\/v2\/posts\/343\/revisions\/1232"}],"wp:attachment":[{"href":"http:\/\/micromouseusa.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=343"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/micromouseusa.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=343"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/micromouseusa.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=343"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}