EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

16 Channel ADC + 16 RC Servo Motor + 1 RS232 + PIC microcontroller

Started by Roberto Hawkowski September 30, 2006
Hello Everyone,

I am a beginner hobbiest in embedded systems.
I want to build a system which will have
   i.   16 channel, 16 bits ADC with SPI interface (it could be two 8
channel ADC)
   ii.  16 RC Servo motor driver (capablity of generating 1-2ms RC
servo pulses with 10 bits resolution, for 16 RC servo motors)
   iii.  1 RS232 port to communicate with a PC
   iv.  PIC microcontroller (all the above devices will be operated by
a PIC Microcontroller)


PIC will run the following algorithm;

    A. Initialise devices
    B. Create a timer interrupt service routine which will read the 16
analog signals via ADC at 500 times per second and calculate a running
averagefor each channel
    C. Read ADC channels (16 channel, 16 bits resolution) and calculate
running averages for each channel
    D. Transmit the calculated averages (16 channel, 16 bits
resolution) to a PC via RS232 channel
    E.  Every 20ms. the RC servo motor positions (10 bits resolution)
data will be updated with the calculated averages
    F. Goto step C


I will borrow an ICD-2 and MPLAB for the project and I will use
Microchip's PIC C compiler.

Can someone out there with PIC and MPLAB experience help me on PIC-C
code segments for
   I.  How to create an interrrupt service routine which will be called
500 times per second?
   II. How to read data from SPI devices?
   III. How to generate 16 RC servo pulses with 10 bit resolution (this
seems to be the most difficult)?
  IV. How to send data via RS232?

I do appreciate if you can share your PIC C code snips.

Thank you


Roberto Hawkowski

In article <1159669255.424580.163820@m7g2000cwm.googlegroups.com>, 
robertohawkowski@yahoo.com.au says...
> Hello Everyone, > > I am a beginner hobbiest in embedded systems. > I want to build a system which will have > i. 16 channel, 16 bits ADC with SPI interface (it could be two 8 > channel ADC) > ii. 16 RC Servo motor driver (capablity of generating 1-2ms RC > servo pulses with 10 bits resolution, for 16 RC servo motors) > iii. 1 RS232 port to communicate with a PC > iv. PIC microcontroller (all the above devices will be operated by > a PIC Microcontroller) > > > PIC will run the following algorithm; > > A. Initialise devices > B. Create a timer interrupt service routine which will read the 16 > analog signals via ADC at 500 times per second and calculate a running > averagefor each channel > C. Read ADC channels (16 channel, 16 bits resolution) and calculate > running averages for each channel > D. Transmit the calculated averages (16 channel, 16 bits > resolution) to a PC via RS232 channel
Do you mean to send the 16 averages only once per second, or 500 times per second as you update the running average? Over what time interval do you do the running average? Or perhaps you mean that you do a fixed average of the last second's worth of data, then send that average once per second? A real "1-second running average" would have you storing the 500 readings in an array, and each time you update, you throw out the oldest value, add in the newest, compute the average, and send that value 500 times per second. I don't think you'll be doing that on a PIC with RS-232! ;-)
> E. Every 20ms. the RC servo motor positions (10 bits resolution) > data will be updated with the calculated averages > F. Goto step C > > > I will borrow an ICD-2 and MPLAB for the project and I will use > Microchip's PIC C compiler. > > Can someone out there with PIC and MPLAB experience help me on PIC-C > code segments for > I. How to create an interrrupt service routine which will be called > 500 times per second? > II. How to read data from SPI devices? > III. How to generate 16 RC servo pulses with 10 bit resolution (this > seems to be the most difficult)?
You are asking for 16 timing pulses with 1-microsecond resolution. This could be a tough job to handle in software. One way to reduce the overhead might be to use a single timer, and break the 50-millisecond update interval into 16 intervals of 3 milliseconds (with a few msec left over). Service a different servo output in each interval using another timer to set an interrupt at the proper ending time, and having the service routines set and clear a different pin each time. Given the response time of the servos, there is probably no need to update them all at the same time, so spread the chore over the 50-msec update interval. With 3 milliseconds in each interval, you probably have the time to collect the data , send the results, and still be ready for the next channel.
> IV. How to send data via RS232? > > I do appreciate if you can share your PIC C code snips. > > Thank you > >
This sounds possible---but hardly what I'd pick for my first PIC project! Mark Borgerson
On 30 Sep, in article
     <1159669255.424580.163820@m7g2000cwm.googlegroups.com>
     robertohawkowski@yahoo.com.au "Roberto Hawkowski" wrote:

>Hello Everyone, > >I am a beginner hobbiest in embedded systems. >I want to build a system which will have > i. 16 channel, 16 bits ADC with SPI interface (it could be two 8 >channel ADC)
Why 16bit ADC? Seems overkill as you are taking a 500 point moving average of them. Then only using the top 10 bits for driving the servo! (see later)
> ii. 16 RC Servo motor driver (capablity of generating 1-2ms RC >servo pulses with 10 bits resolution, for 16 RC servo motors) > iii. 1 RS232 port to communicate with a PC > iv. PIC microcontroller (all the above devices will be operated by >a PIC Microcontroller)
WHY have you chosen PIC? WHICH PIC have you chosen?
>PIC will run the following algorithm; > > A. Initialise devices > B. Create a timer interrupt service routine which will read the 16 >analog signals via ADC at 500 times per second and calculate a running
Hmm for single A/D with 16 channel mux 16 x 500 = 8000 Hz conversion rate If each channel at end of conversion needs to be serviced then you would need to service 8000 interupts per second. If the SPI device can send the block of 16 results then you need to look at the transfer speed of your SPI to send 32 bytes, 500 times per second. Then see if you bitbang the SPI to do this speed as well as everything else. You will probably need 32bytes of buffer storage to collect them into.
>averagefor each channel
Do you mean a 500 point moving average or a 10 point moving average. If the average is used to update the servo 50 times a second (every 20ms) then you are only using an effective 10 point moving average between updates. The delay on any action will be about half a second before a 1bit change in the RC servo will occur, so you will be updating the servos with new values less often than sending pulses to them. To perform a moving average in fastest possible way you need to store 500 values (each 16bit) and a running total which would need to be 25bit bit at least (in reality 32bit), to subtract oldest value from running total, overwrite oldest value with newest value, add in newest value, which means you will need a 9 bit index (16bit in reality) for all channels or one for each channel, depending on how software structured. Then of course you will always be dividing running total by 500 for the current average point in 16 bit then only use top 10 bits. So data storage requirements are 16 x 16bit 32 bytes (SPI input buffer) 16 x 32bit 48 bytes (running totals) 16 x 500 x 16bit 16000 bytes (old values) 16 x 16bit 32 bytes (array index) 16112 bytes ===== You do have a PIC with about 32kB of RAM don't you?
> C. Read ADC channels (16 channel, 16 bits resolution) and calculate >running averages for each channel
500 or 10 point average? Personally 10 or 12 bit ADC would do with 10 or 16 point moving average.
> D. Transmit the calculated averages (16 channel, 16 bits >resolution) to a PC via RS232 channel
At what speed and how often, as I doubt you will be able to do more than once a second in binary and another 32byte buffer for the data. I doubt you have thought about framing the data.
> E. Every 20ms. the RC servo motor positions (10 bits resolution) >data will be updated with the calculated averages > F. Goto step C > > >I will borrow an ICD-2 and MPLAB for the project and I will use >Microchip's PIC C compiler. > >Can someone out there with PIC and MPLAB experience help me on PIC-C >code segments for > I. How to create an interrrupt service routine which will be called >500 times per second? > II. How to read data from SPI devices? > III. How to generate 16 RC servo pulses with 10 bit resolution (this >seems to be the most difficult)? > IV. How to send data via RS232?
Why are you trying to do all this without planning out your data requirements? Why have you chosen the processor first, without seeing if it is possible first?
>I do appreciate if you can share your PIC C code snips.
This makes it look like a please do my homework question.
>Thank you > > >Roberto Hawkowski > >
-- Paul Carpenter | paul@pcserviceselectronics.co.uk <http://www.pcserviceselectronics.co.uk/> PC Services <http://www.gnuh8.org.uk/> GNU H8 & mailing list info <http://www.badweb.org.uk/> For those web sites you hate
Mark Borgerson wrote:
> In article <1159669255.424580.163820@m7g2000cwm.googlegroups.com>, > robertohawkowski@yahoo.com.au says... >> Hello Everyone, >> >> I am a beginner hobbiest in embedded systems. >> I want to build a system which will have >> i. 16 channel, 16 bits ADC with SPI interface (it could be two 8 >> channel ADC) >> ii. 16 RC Servo motor driver (capablity of generating 1-2ms RC >> servo pulses with 10 bits resolution, for 16 RC servo motors) >> iii. 1 RS232 port to communicate with a PC >> iv. PIC microcontroller (all the above devices will be operated by >> a PIC Microcontroller) >> >> >> PIC will run the following algorithm; >> >> A. Initialise devices >> B. Create a timer interrupt service routine which will read the 16 >> analog signals via ADC at 500 times per second and calculate a running >> averagefor each channel >> C. Read ADC channels (16 channel, 16 bits resolution) and calculate >> running averages for each channel >> D. Transmit the calculated averages (16 channel, 16 bits >> resolution) to a PC via RS232 channel > > > Do you mean to send the 16 averages only once per second, or 500 times > per second as you update the running average? > > Over what time interval do you do the running average? > > Or perhaps you mean that you do a fixed average of the last second's > worth of data, then send that average once per second? > > A real "1-second running average" would have you storing the 500 > readings in an array, and each time you update, you throw out the oldest > value, add in the newest, compute the average, and send that value > 500 times per second. I don't think you'll be doing that on a PIC > with RS-232! ;-)
wouldn't it be far much easier to use a simple RC-filter in hardware ? You're going to need it anyway, to prevent aliasing ! And indeed 16 bit is a whole lot. For the RS232 it's not a real problem, my standard Baudrate is 1.25 MB !!
> >> E. Every 20ms. the RC servo motor positions (10 bits resolution) >> data will be updated with the calculated averages >> F. Goto step C >> >> >> I will borrow an ICD-2 and MPLAB for the project and I will use >> Microchip's PIC C compiler. >> >> Can someone out there with PIC and MPLAB experience help me on PIC-C >> code segments for >> I. How to create an interrrupt service routine which will be called >> 500 times per second? >> II. How to read data from SPI devices? >> III. How to generate 16 RC servo pulses with 10 bit resolution (this >> seems to be the most difficult)? > > You are asking for 16 timing pulses with 1-microsecond resolution.
I think 20 msec, 10 bit is 20 usec = 100 instructions, that's possible (if you don't have to do many other tasks) and you have a good compiler or write in assembler. This
> could be a tough job to handle in software. One way to reduce the > overhead might be to use a single timer, and break the 50-millisecond > update interval into 16 intervals of 3 milliseconds (with a few msec > left over). Service a different servo output in each interval using > another timer to set an interrupt at the proper ending time, and having > the service routines set and clear a different pin each time. > > Given the response time of the servos, there is probably no need > to update them all at the same time, so spread the chore over > the 50-msec update interval. With 3 milliseconds in each interval, > you probably have the time to collect the data , send the > results, and still be ready for the next channel. > > >> IV. How to send data via RS232? >> >> I do appreciate if you can share your PIC C code snips. >> >> Thank you >> >> > This sounds possible---but hardly what I'd pick for my first PIC > project!
Indeed blink a LED first ! cheers, Stef
> > > Mark Borgerson > >
Paul Carpenter wrote:
> On 30 Sep, in article > <1159669255.424580.163820@m7g2000cwm.googlegroups.com> > robertohawkowski@yahoo.com.au "Roberto Hawkowski" wrote: > >> Hello Everyone, >> >> I am a beginner hobbiest in embedded systems. >> I want to build a system which will have >> i. 16 channel, 16 bits ADC with SPI interface (it could be two 8 >> channel ADC) > > Why 16bit ADC? Seems overkill as you are taking a 500 point moving average > of them. Then only using the top 10 bits for driving the servo! (see later) > >> ii. 16 RC Servo motor driver (capablity of generating 1-2ms RC >> servo pulses with 10 bits resolution, for 16 RC servo motors) >> iii. 1 RS232 port to communicate with a PC >> iv. PIC microcontroller (all the above devices will be operated by >> a PIC Microcontroller) > > WHY have you chosen PIC? > > WHICH PIC have you chosen? > >> PIC will run the following algorithm; >> >> A. Initialise devices >> B. Create a timer interrupt service routine which will read the 16 >> analog signals via ADC at 500 times per second and calculate a running > > Hmm for single A/D with 16 channel mux > > 16 x 500 = 8000 Hz conversion rate > > If each channel at end of conversion needs to be serviced then you would > need to service 8000 interupts per second. If the SPI device can send the > block of 16 results then you need to look at the transfer speed of > your SPI to send 32 bytes, 500 times per second. Then see if you > bitbang the SPI to do this speed as well as everything else. > > You will probably need 32bytes of buffer storage to collect them into. > >> averagefor each channel > > Do you mean a 500 point moving average or a 10 point moving average. If the > average is used to update the servo 50 times a second (every 20ms) then > you are only using an effective 10 point moving average between updates. > The delay on any action will be about half a second before a 1bit change > in the RC servo will occur, so you will be updating the servos with new > values less often than sending pulses to them. > > To perform a moving average in fastest possible way you need to store > 500 values (each 16bit) and a running total which would need to be > 25bit bit at least (in reality 32bit), to subtract oldest value from > running total, overwrite oldest value with newest value, add in newest > value, which means you will need a 9 bit index (16bit in reality) for > all channels or one for each channel, depending on how software structured. > Then of course you will always be dividing running total by 500 for > the current average point in 16 bit then only use top 10 bits. > > So data storage requirements are > > 16 x 16bit 32 bytes (SPI input buffer) > 16 x 32bit 48 bytes (running totals) > 16 x 500 x 16bit 16000 bytes (old values) > 16 x 16bit 32 bytes (array index) > > 16112 bytes > ===== > > You do have a PIC with about 32kB of RAM don't you? > >> C. Read ADC channels (16 channel, 16 bits resolution) and calculate >> running averages for each channel > > 500 or 10 point average? > > Personally 10 or 12 bit ADC would do with 10 or 16 point moving average. > >> D. Transmit the calculated averages (16 channel, 16 bits >> resolution) to a PC via RS232 channel > > At what speed and how often, as I doubt you will be able to do more > than once a second in binary and another 32byte buffer for the data. > I doubt you have thought about framing the data. > >> E. Every 20ms. the RC servo motor positions (10 bits resolution) >> data will be updated with the calculated averages >> F. Goto step C >> >> >> I will borrow an ICD-2 and MPLAB for the project and I will use >> Microchip's PIC C compiler. >> >> Can someone out there with PIC and MPLAB experience help me on PIC-C >> code segments for >> I. How to create an interrrupt service routine which will be called >> 500 times per second? >> II. How to read data from SPI devices? >> III. How to generate 16 RC servo pulses with 10 bit resolution (this >> seems to be the most difficult)? >> IV. How to send data via RS232? > > Why are you trying to do all this without planning out your data requirements? > > Why have you chosen the processor first, without seeing if it is possible > first? > >> I do appreciate if you can share your PIC C code snips. > > This makes it look like a please do my homework question. > >> Thank you >> >> >> Roberto Hawkowski >> >> >
I can not be homework. A 16 Bit ADC is a job for a top professional. It is a non-starter for a beginner. The Same with th RC servos for a 180 degree servo that is .25 degree resolution. Standard $20 servos are not that accurate. The SPI and RS232 are built -in to the mid to bigger chips. www.microchipC.com should have many samples

The 2024 Embedded Online Conference