PDA

View Full Version : Servo control / UART / SPI help needed



Blackhawk
- 8th November 2006, 12:31
The current project I am working on is a rocket datalogger/control system and I've been running into walls all throughout PICBASIC.

The basic specs for the whole system are as follows:

- PIC16F877a at the core, running at 20MHz (first annoyance as PICBASIC does not allow for changing xtal speeds, everything runs 5 times faster than it should).

- 16 channel multiplexer feeding a 16 bit ADC. I don't care if the ADC output is serial or parallel or any other strange protocol, however it needs to be capable of at least 2ksps. Clearly parallel would be easier for me to code but it's giving me other I/O problems. As for serial data transfer I'm not sure how I can get the PIC to interface with the ADC in either multi-line serial, SPI etc communication. My main problem is that the ADC is looking to directly output a word variable whereas the PIC serial coms only take byte variables directly. I could bit bash but I would REALLY hate to do that.
- Store data in a bank of 8 I2C eeproms. Not much of an issue, have to hack around in the include files to change the I2C port to the correct port and pins though, a pain but I can live with it.

- Control 4 servo motors. Not an issue if I have portB clear, however assuming I'm using the USART port on the PIC I only have one full 8 I/O port left, this isn't enough if I'm using a parallel 16bit ADC. Clearly the solutions are to either control the servos directly through code or use a serial ADC. Failing me learning how to manipulate 16bit serial communication with an 8bit core I can't actually manually drive the servos because PICbasic only lets you delay for integer milliseconds, enough to run a servo from full to opposite full. Even knowing that my clock speed is actually going to be 5 times faster, so I can time down to 200 microseconds doesn't really help because this doesn't give me any resolution. Last ditch effort I suppose would be to connect the servos through a smaller PIC on portb, and to communicate to that PIC via serial but that's messy every way you look at it.

I'm only a student and this is just a hobby so I can't afford the pro version, I probably would have bought it initially however if I knew exactly how shocking the basic version is when dealing with more than turning LED's on and off.

sayzer
- 8th November 2006, 12:41
If you could list down your questions, it would be a lot easier to understand what you want to have.

It is being more complicated the way you described above.


---------------------

Blackhawk
- 8th November 2006, 12:47
ok here goes:

1) Is there any way I can use the hardware communication of the 16F877a (USART, SPI etc) to communicate with a 16bit ADC, which wants to send its data as words.
2) If not, is there any way of controlling servo motors without using portB. For example can I somehow make my PIC accurately control pulses of 10 microseconds or so, without using the pulseout command (which is tied to portB only).

That’s basically it.

Dave
- 8th November 2006, 21:28
Blackhawk, As sayzer said if you could please give us some more definition of your problem it would help. What I don't understand is the phrase "- PIC16F877a at the core, running at 20MHz (first annoyance as PICBASIC does not allow for changing xtal speeds, everything runs 5 times faster than it should)." Do you want the pic to run slower or faster? Also I don't understand the phrase "I can't actually manually drive the servos because PICbasic only lets you delay for integer milliseconds" There is a 16 bit timer or 2 inside the 16F877 which will allow 1 tick to be as small as the osc freq. / 4. Also there is a PAUSEUS command that will allow timing to about 2uS. Which 16 bit A to D convertor are you using?

Dave Purola,
N8NTA

Blackhawk
- 9th November 2006, 02:13
Blackhawk, As sayzer said if you could please give us some more definition of your problem it would help. What I don't understand is the phrase "- PIC16F877a at the core, running at 20MHz (first annoyance as PICBASIC does not allow for changing xtal speeds, everything runs 5 times faster than it should)." Do you want the pic to run slower or faster? Also I don't understand the phrase "I can't actually manually drive the servos because PICbasic only lets you delay for integer milliseconds" There is a 16 bit timer or 2 inside the 16F877 which will allow 1 tick to be as small as the osc freq. / 4. Also there is a PAUSEUS command that will allow timing to about 2uS. Which 16 bit A to D convertor are you using?

Dave Purola,
N8NTA

Remember I'm not using the pro version of the compiler!

There is no way to set the oscillator frequency for your circuit, so while my oscillator is a 20MHz crystal the program is compiled for a 4MHz crystal. As such any compiled delay will be 5 times shorter than it should be.

Also there is no pauseus command in the non-pro version of the compiler, only the command pause which only pauses down to integer milliseconds.

I have not chosen the A/D converter yet because I was wondering if anyone here would be able to help me with the transfer protocol. How exactly would I set up a serial interface to receive a 16bit word instead of 2 8bit bytes?

The main problem I think you people are having with understanding my issues is that you all have the pro version of the compiler, if I had the pro version I would have no problems.

keithdoxey
- 9th November 2006, 11:41
A 16 bit word is sent as two bytes because the registers in the UART are 8 bit. Send the two bytes and reassemble them into a word at the far end

A 10mS pause is easy.... PAUSE 50

Because your PIC is running 5 times as fast as the compiler thinks it is, all delays will be a fifth of what it expects so the 50mS pause will become 10mS.

Blackhawk
- 9th November 2006, 12:54
I want a 10 microsecond pause not a 10 millisecond pause, that's the problem.

As for the serial sending, look up the datasheet for the TLC4541, one of the ADC's I was considering. It sends it's word output as a single, un-broken word, not as two bytes with a stop bit in between, that is my problem.

sayzer
- 9th November 2006, 15:27
...
A 10mS pause is easy.... PAUSE 50

Because your PIC is running 5 times as fast as the compiler thinks it is, all delays will be a fifth of what it expects so the 50mS pause will become 10mS.

This is not valid for PAUSE command. It is for PULSOUT type of commands.



I want a 10 microsecond pause not a 10 millisecond pause, that's the problem


With at least 10Mhz OSC, 10uS pause can be achieved using PAUSEUS command. Since you are using 20Mhz, it WOULD BE ok in your case by PAUSEUS 10 but you are not using PBP. So it won't be possible until you get PBP.

Therefore, you will need to use ASM routine to create a sensitive uS delay.



-------------------------------------

paul borgmeier
- 9th November 2006, 17:40
Therefore, you will need to use ASM routine to create a sensitive uS delay.
Not so - try this (with 20Mhz xtal 4 instructions = 1 uS)


Main:

Gosub Delay_10 ' 10 uS delay
Gosub Delay_1 ' 1 us delay

GOTO Main

' *** Delay 10 us Subroutine (2 instructions to get here and 2 to get back)
Delay_10:
Gosub Delay_1
Gosub Delay_1
Gosub Delay_1
Gosub Delay_1
Gosub Delay_1
Gosub Delay_1
Gosub Delay_1
Gosub Delay_1
Gosub Delay_1
Return

' *** Delay 1 us Subroutine (2 instructions to get here and 2 to get back)
Delay_1:
Return

END

sayzer
- 9th November 2006, 17:48
hehe :)

Clever!


--------------------------------

Blackhawk
- 10th November 2006, 04:40
Thanks for the help, I was wondering if I could uselessly move bits around to get the delay but I didn't know exactly how long the processes would take.