CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug Reports on this forum. Send them to support@ccsinfo.com

Question regarding read_adc

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Billy9689



Joined: 01 Dec 2017
Posts: 24

View user's profile Send private message

Question regarding read_adc
PostPosted: Wed Dec 20, 2017 2:45 am     Reply with quote

Hi guys. I would like to ask something about read_adc.
Lets say I want to read light intensity data from an array of pixel, say a 3x3 pixel array. From what I read about the read_adc function, it seems like it will read the data as a whole unit, where data from all 9 pixels are grouped together. (correct me if I am wrong) Is there any way that I can read from a specific pixel only, say pixel 5 ?

Further information: The pixel array are integrated in an image sensor so it is not possible to dissemble it.
Ttelmah



Joined: 11 Mar 2010
Posts: 13271

View user's profile Send private message

PostPosted: Wed Dec 20, 2017 4:03 am     Reply with quote

If the array is only giving one output, then there is only one signal to read. The read_adc function can't create something from nothing....
However if the array gives multiple output pins, then these can be connected to separate adc input pins and read separately.
What is the actual array?.
How are you getting at the voltage?.
If this is being read from some multiplexed device like a scanned LED array, then you would need to time the reading to get the value from any particular pixel. Whether there is time to actually do this would depend on how fast the matrix is being scanned, and the ADC on your PIC.
Billy9689



Joined: 01 Dec 2017
Posts: 24

View user's profile Send private message

PostPosted: Wed Dec 20, 2017 6:14 am     Reply with quote

Well the array are 40x120 pixel array. Previously in wired version, readout is done by a program, where it will scan each pixels in the first column, then proceed to second column and so on. All output from the pixel will then be stored in a tab delimited file. So now I want to simplify the readout. I just want the reading from a certain pixel so I wonder whether or not I can program it to just read from a certain pixel. For your information the output from the pixel array is connected to one adc pin only as they all belong to the same image sensor.
temtronic



Joined: 01 Jul 2010
Posts: 6157
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Dec 20, 2017 6:45 am     Reply with quote

Well providing you have access to the rows and columns, reading a single pixel is easy. The matrix is 40 by 120, so 6 bits could be columns, then 7 bits for 120 rows to be read, though it might be better the other way...120 rows, 6 columns. A PIC with 6 ADC inputs could read all 6 pixels, thus faster. In any case it's simple to have the PIC select a pixel then read the data. Without knowing any specifics of the 'image device' I can't go further.
Intel has a great appnote (yeah 20+ years old) on doing this, I used as the basis of a 16 by 16 imager made from TO-18 canned phototransistors for a robotic eye.

Jay
Billy9689



Joined: 01 Dec 2017
Posts: 24

View user's profile Send private message

PostPosted: Wed Dec 20, 2017 7:00 am     Reply with quote

Quote:
A PIC with 6 ADC inputs could read all 6 pixels, thus faster.
 
6 ADC inputs here means 6 bits ADC? The pic I used is DSPIC33EP256MU806. According to the spec sheet it can go up to 12 bits.

Honestly speaking I am a beginner in microcontroller programming so there are many thing that I don't know about.

So please advise...
temtronic



Joined: 01 Jul 2010
Posts: 6157
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Dec 20, 2017 7:49 am     Reply with quote

hmm beginner and using a DSPIC !! yikes, I've got 20+ years of PICs under my belt and I stay away from DSPICs, too dang complicated for an old guy like me.
If the 'image sensor' can be accessed (used) as an array of 120 rows and 40 columns, then the PIC needs 7 bits to decode (control) the 120 rows. It only needs 6 bits to decode the 40 columns. This is 'generally' how matrix devices work.....
What is totally unknown is HOW the 'image sensor' is made. Without a spec sheet, link, or other documentation I can't advise how to proceed.
As a beginner I would NOT recommend the DSPIC series of PICs and interfacing to an 'image sensor' would NOT be 'My first PIC project'. While PICs are simple in nature (35+- instructions), they have matured over the years, becoming faster and more powerful. Even with the CCS compilers, getting a PIC to do what you can be challenging.
Hopefully you have a good grasp of C (I don't) and have a LOT of time on your hands. As a 'concept' getting a PIC to 'read a pixel, display the result' is easy...it's all in the 'details'.
Post the image sensor info, so we can see if it's even possible.
Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 13271

View user's profile Send private message

PostPosted: Wed Dec 20, 2017 7:51 am     Reply with quote

No.

The number of bits is the resolution.

Oh dear, you have some real basics to learn.

An ADC that can distinguish two 'levels' to the incoming signal, would be a 'one bit; ADC (on/off). An ADC that can distinguish four 'levels' (a quarter on', half on, three quarters on, and full on), is a two bit ADC. Most PIC's offer 10bit ADC's (1024 levels), some give 12bit (4096 levels), and a few 14 or even 16bit.
The number of bits has nothing to do with the number of inputs that can be selected.

There are 8pin PIC's (only 6 inputs possible), that still offer 10bit ADC's.

Most of the PIC's have the option to connect the ADC to different pins, so you can connect it to (say) PIN1, and read a value, then connect to pin 2 and read another value, then back to pin 1 and read the first value again etc....
Your PIC can actually read up to 24 different pins.

This goes back to my questions:

What is the actual array?.
How are you getting at the voltage?.

You need to give us some details.

However I also have to comment. It sounds as if what you want to do will involve you in a lot of learning. This is not a quick job.

I see Temtronic said almost the same things while I was typing...
Billy9689



Joined: 01 Dec 2017
Posts: 24

View user's profile Send private message

PostPosted: Thu Dec 21, 2017 8:10 pm     Reply with quote

Ya I know I have a steep learning curve. I try to consult some friends who are doing programming and they said so too. But this work is assign by my supervisor for my PhD. His idea was since my senior had completed modified our sensor from serial cable version to usb version using the same microcontroller, I should have no problem converting it to wireless version. But it seems like I still have much problem. I use the same read adc way as he do but the result doesn't seems right to me. Sad

Anyway end of the complain. Let's go back to the problem.

Firstly, I'm not sure whether this is what Mr. Ttlemah asked or not. The array is 40x120, where all of them are active pixel sensor (APS). All the output from the APS are cnnected to the same output port and the output port is connected to the ADC pin on the PIC (pin 14). The power supply to the device (containing the PCB with PIC, Bluetooth module and the image sensor) is 3.3 V, where it should be power up using battery . However with battery the Bluetooth is not working properly (either keep disconnecting or not working at all) so temporarily I am using the PICKIT 3 VDD and GND port to power it up and it works properly. However, the read adc part still not looking correct to me. The output should be varies with the light intensity illuminated on the sensor, but it doesn't seems to be the case. The output remained whether I shaded the sensor or expose it to light and it keep give me strange reading (not hex value for numbers and the output from the sensor should be number). Anyway I attached the code below so that you guys can take a look. By the way, there are no spec sheet for the image sensor as it is developed by ourselves...

Code:
#include <33EP256MU806.h>
#device ADC=12
#use delay(crystal=8Mhz, clock=120Mhz, LOCK)
#fuses NOWDT, NOPROTECT

#pin_select U1TX=PIN_F4
#pin_select U1RX=PIN_F3
#use rs232(baud=19200, UART1, bits=8, parity=N, errors) //enable interrupt receive buffer

#define pixels 5324
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

void BT_wake (void)
{
   output_low(PIN_F1); //disable sleep on Bluetooth module
   while (input(PIN_G6)==0)
       ; //wait if chip is in a hardware reset
   output_low(PIN_G6); //set low to mode pin on Bluetooth module
   delay_ms(1);
   output_float(PIN_G6); //release line
   while (input(PIN_G6)==0)
       ; //wait for the chip to finish resetting
}

void startup (void)
{
   puts("TXDT BA"); //Output BA
   putc('\r'); //CR
   putc('\n'); //LF
   delay_ms (1000);
   puts("TXDT B1");  //Output B1
   putc('\r'); //CR
   putc('\n'); //LF
   delay_ms (1000);
}

void intro (void)
{
   puts("TXDT C1BA10"); //Output
   putc('\r'); //CR
   putc('\n'); //LF
   delay_ms (1000);
}

void ending (void)
{
   puts("TXDT C0FFEE"); //Output C0FFEE
   putc('\r'); //CR
   putc('\n'); //LF
   delay_ms (1000);
   
}
void adc_setting (void)
{
   setup_adc_ports (SAN2, VSS_VREF); //setup ADC pin 14 External Vref
   setup_adc (ADC_CLOCK_DIV_32 | ADC_TAD_MUL_0); //TAD = (32/60 MHz) = 533 ns
   set_adc_channel (2);
   delay_us (100);
}

void main(void)

   long ADC_value;
   char out [100] = "TXDT ";
   //char outt [100];
   char volt [20000];
   //int hi_volt, lo_volt;
   int i = 0;
   BT_wake(); //wake the chip
   delay_ms (20000); //delay 1/3 minutes to establish connection
   startup (); //Output some introductory message after startup
   adc_setting ();
   while (true)
   {
   intro (); //output some message so that I know the output from ADC is coming next
   output_high(PIN_E5); //send high to clock (pin E5)
   ADC_value = read_adc (); //read adc
   volt [i] = make8(ADC_value, 1);
   i++;
   volt [i] = make8(ADC_value, 0);
   output_low(PIN_E5); //send low to clock (pin E5)
   strcat (out, volt);
   puts (out); //send via bluetooth
   putc('\r'); //CR
   putc('\n'); //LF
   delay_ms (1000);
   //delay_ms (1000);
   out = "TXDT ";
   i = 0;
   ending (); //output some message so that I know the output from ADC had ended
   }
}


Previously I asked a lot of question regarding the receiving command from Bluetooth (Title: Bluetooth not receiving on UART). While it is still not working, my supervisor asked me to work on reading from the sensor and send via Bluetooth first, as the sending part is ok. Really appreciate if you guys can help me.

Thank you.
PCM programmer



Joined: 06 Sep 2003
Posts: 20337

View user's profile Send private message

PostPosted: Thu Dec 21, 2017 11:53 pm     Reply with quote

Billy9689 wrote:

It keep give me strange reading (not hex value for numbers and the output from the sensor should be number).

You are using functions that operate on ASCII strings, but you have not
converted the ADC result to ASCII.
Billy9689 wrote:

while (true)
{
intro (); //output some message so that I know the output from ADC is coming next
output_high(PIN_E5); //send high to clock (pin E5)
ADC_value = read_adc (); //read adc
volt [i] = make8(ADC_value, 1);
i++;
volt [i] = make8(ADC_value, 0);
output_low(PIN_E5); //send low to clock (pin E5)
strcat (out, volt);
puts (out); //send via bluetooth
putc('\r'); //CR
putc('\n'); //LF
delay_ms (1000);
//delay_ms (1000);
out = "TXDT ";
i = 0;
ending ();
}



Look at this thread. It shows how you can read an ADC value and then
use sprintf() to convert it to ASCII string and put it into an array.
Once you have done that, then you can use strcat() or other string functions.
http://www.ccsinfo.com/forum/viewtopic.php?t=55078
Billy9689



Joined: 01 Dec 2017
Posts: 24

View user's profile Send private message

PostPosted: Fri Dec 22, 2017 12:21 am     Reply with quote

Quick question to PCM programmer: You suggest that I stored the result from make8 into a char array is not correct, right? So how about I do like code below?
Code:
 void main (void)
{
   long ADC_value;
   char volt [20000];
   int hi_volt, lo_volt;
   // Some setting etc..//
   while (true)
   {
   intro (); //output some message so that I know the output from ADC is coming next
   output_high(PIN_E5); //send high to clock (pin E5)
   ADC_value = read_adc (); //read adc
   hi_volt = make8(ADC_value, 1);
   lo_volt = make8(ADC_value, 0);
   output_low(PIN_E5); //send low to clock (pin E5)
   sprintf (out, "TXDT %u", hi_volt); //combine MSB with Bluetooth header
   puts (out); //send via bluetooth
   putc('\r'); //CR
   putc('\n'); //LF
   delay_ms (1000);
   sprintf (out, "TXDT %u", lo_volt); //combine LSB with Bluetooth header
   puts (out); //send via bluetooth
   putc('\r'); //CR
   putc('\n'); //LF
   delay_ms (1000);
   ending (); //output some message so that I know the output from ADC had ended
   }
}

And I will try to study the example you give as well.
Ttelmah



Joined: 11 Mar 2010
Posts: 13271

View user's profile Send private message

PostPosted: Fri Dec 22, 2017 1:50 am     Reply with quote

The point I was asking, is how the ADC is meant to get 'at' the specific pixel(s).
If it is CMOS image sensor, then the answer is probably 'time'. The data is actually a stream of values from the pixels, with a synchronising clock.
So appearing on the ADC pin you have a stream PIX1, PIX2, PIX3, PIX4.....
While at the same time there is a clock signal, and probably a frame and line signal as well.
Now this implies the PIC is going to need access to these clock signals so it knows where it is in the stream.
Currently you seem to just be reading the voltage and 'hoping' to hit a pixel....

Then on just reading specific pixels, it is just going to be a matter of counting to the required pixel before taking the reading(s).

Now there is then the question of the data rate?. Is the PIC ADC actually fast enough to sample and read a pixel in the time it is available on the pin?. Your comments earlier about having read the whole array suggests so, but many (most) such sensors actually clock well above the rate the PIC would be able to do this. Remember the signal has to be stable for Tsamp before you even start doing the actual conversion. The sensors like this I've used typically clock at several MHz.... If you have exactly the right CPU clock, the ADC on your PIC can be clocked up to 13.15MHz. It takes a minimum of 14 clocks to perform a sample and conversion ( 10bit mode, and this assumes your signal source has a low impedance). With 10 bit, you can save a cycle on this by overlapping sampling with the two ADC's. So the absolute best implies a pixel clock that is just over 1Mhz max. You have ADC=12 selected, which halves the rate at which you can sample. 500KHz max. What _is_ the clock rate of the sensor?. The thing then is that if the data rate is 'pushing' towards this high, you can't think about doing this manually. You'd need to be doing the readings using DMA, and have this setup in advance, and possibly trigger using a CCP to start a specified number of conversions automatically.

You need to understand your sensor before starting to even think about code.

You clock one pin, which suggests this might be the pixel clock, but I can't believe any sensor would operate with a clock so slow (you delay for an age between clocks). Even if the sensor is 'in house' there must be a timing design for it, and details of how the sequence of data arrives at the output pin. If the clock you generate actually switches the data to the next pixel, the ADC needs to have sampling time before you read it. This is specified by the ADC_TAD_MUL_xx value in the ADC setup. Currently zero, which allows no time for sampling....
temtronic



Joined: 01 Jul 2010
Posts: 6157
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Dec 22, 2017 4:13 pm     Reply with quote

OK, how about going 'back to square one' ? You say you've got working code with a serial interface (I assume to a PC). It'd be interesting to see THAT code since I have no idea HOW you can get data from a specific pixel.
Without the details about the image sensor, there are just too many variables to deal with. In theory it's an easy program:
Code:

start
acquire data
send data
loop to start...
...
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group