Continue to Site

# Hardware ESC 8xSERVO CONTROL on PIC (Oshonsoft BASIC)

#### camerart

##### Active Member
Hi M,
The 164 in the title, tells me it's since the 'shift register'
so if you edit it, change the title, date time:
'18F4431 32MHz XTL REMOTE_SLAVE 164 371 020223 2330
C

#### camerart

##### Active Member
Hi m,
After the initial LED flashes, then they stay ON.
i Loops 0-9
CNT loops 0-20
wordtemp loops 1xtime
servocount seems to stay at 0, but I did see a 4 once.

Off to bed
Cheers.
C

#### Pommie

##### Well-Known Member
3rd BREAK
2005.12 us
ms =1
CNT = 1
SERVOPOS() 0-8 filled
i=9
Rest '0'
This is worrying as servoPos is being initiated after interrupts are enabled.

You need to move these two lines further down,
Enable High 'This is set for SERVOS
Enable Low 'This is set for GPS later

To after these two,
INTCON.PEIE = 1
INTCON.GIE = 1

1st BREAK
0.12us
all '0'
I don't see how this is possible. 0.12uS is 1 clock cycle.
Assuming the break point is in the ISR then the first thing it's doing is executing the ISR which it shouldn't be doing as nothing is setup. Or, is it mS?

One thing that's just occurred to me, there is no longer any interrupt priority used, should it still be "On High Interrupt"?

Mike.

#### Pommie

##### Well-Known Member
'18F4431 32MHz XTL REMOTE_SLAVE 164 371 020223 2330
The last one I've got is 18F4431 32MHz XTL REMOTE_SLAVE 164 3 020223 1600.txt

Mike.

Last edited:

#### camerart

##### Active Member
This is worrying as servoPos is being initiated after interrupts are enabled.

You need to move these two lines further down,
Enable High 'This is set for SERVOS
Enable Low 'This is set for GPS later

To after these two,
INTCON.PEIE = 1
INTCON.GIE = 1

I don't see how this is possible. 0.12uS is 1 clock cycle.
Assuming the break point is in the ISR then the first thing it's doing is executing the ISR which it shouldn't be doing as nothing is setup. Or, is it mS?

One thing that's just occurred to me, there is no longer any interrupt priority used, should it still be "On High Interrupt"?

Mike.
G'day M,
As I understand it:
Enable High 'This is set for SERVOS
Enable Low 'This is set for GPS later
should be before MAIN.
They enable the priority of each section.
The SERVO section begins with
On High Interrupt
and the GPS section as it can miss a beat,starts with
On low Interrupt.

The last one CODE I posted was:
18F4431 32MHz XTL REMOTE_SLAVE 164 3 020223 1600.txt

If I posted todays, it woulld be (at the moment:
'18F4431 32MHz XTL REMOTE_SLAVE 164 371 030223 0800
If you edit any and post them, change the time and date,then I'll know it's changed, and me likewise. (Although I don't expect to be changing much as you're in the driiving seat)

1st Break:
Clock cycles =4
Real time duration = 0.12us

Earlier CODE seemed to give better results??
C

#### camerart

##### Active Member
Edit, does the A.I. program get rid of all indenting?
Hi M,
I put 'C' CODE into the AI, and it produces a BASIC shaped INDENTED program, that I can almost read.

I copy that into the OSH SIM, and try to compile.
It stops on the first incorrect line, with an error message, and I have to guess what's wrong.
Sometimes I read the D/S, sometimes the OSH manual, and try till it moces to the next incorrect line, until it all compiles.
Then I run the simulator, while watchin Flags etc, and try to figure out if it's working or not.
For another opinion, I post it on a forum.
If I post is as I did in #369, the INDENTS stay where I left them.
C

#### jjw

##### Member
In #371:
CCPR1L = 0x13
CCPR2H = 0x07
Shouldn't it be CCPR1H

#### camerart

##### Active Member
In #371:
CCPR1L = 0x13
CCPR2H = 0x07
Shouldn't it be CCPR1H
Hi J,
I was only 1 out
That made a difference, well spotted. Reading the SIM numbers still doesn't seem correct.

servocount counts to 3 then 0
i counts to 9 then stays 9
This could be sim speed, and me not seeing the changes. I change the SIM speed to suit, but it needs to be fast slow at the same time, which is impossible.
Thanks.
C

#### camerart

##### Active Member
Hi,
Here is the program since #371 with updated title:
Now #389 This is to make sure that we're working on exactly the same CODE with no hidden edits.
C

#### Attachments

• 18F4431 32MHz XTL REMOTE_SLAVE 164 389 030223 1200.txt
3.5 KB · Views: 28
Last edited:

#### camerart

##### Active Member
Hi M,
Do you have any objection to me posting your CODE on AAC? There are OSH experts there, and may help us.
C

#### Pommie

##### Well-Known Member
No objection at all. Not being able to debug is a major stumbling block.

If someone can printout the timing of the CCP1 output that would be very useful.
Also, confirming that the timer2 interrupt is happening every millisecond.

I note that these two lines,
Enable High 'This is set for SERVOS
Enable Low 'This is set for GPS later
are still at the beginning of the code - lines 38 & 39.
Interrupts should not be enabled until after they are setup but in this case it shouldn't matter as no interrupts will occur until they are setup.

Mike.

#### camerart

##### Active Member
No objection at all. Not being able to debug is a major stumbling block.

If someone can printout the timing of the CCP1 output that would be very useful.
Also, confirming that the timer2 interrupt is happening every millisecond.

I note that these two lines,
Enable High 'This is set for SERVOS
Enable Low 'This is set for GPS later
are still at the beginning of the code - lines 38 & 39.
Interrupts should not be enabled until after they are setup but in this case it shouldn't matter as no interrupts will occur until they are setup.

Mike.
Hi M,
Ok, good. I'll post #349, and if you could point ot the latest 'C' file, I can post that also.

The SIM can watch every cycle, but of course that would take a long time to watch, and it can run fast so that counts etc get missed. I wrote down a sheet of INTERRUPTs, which was interesting, but not fruitful. I can't find a log file, but there may be one, I'll ask.

I have tried removing and adding all of the ENABLES, to see what happens, I couldn't see much of a pattern.

Cheers, C.

#### Pommie

##### Well-Known Member
Here is the latest C file,
Code:
#include <xc.h>
#include "config.c"
#include <stdint.h>
#define _XTAL_FREQ 32000000
#define NUM_SERVOS 10

uint16_t wordTemp;
uint32_t ms;
uint8_t count=0,servoCount;
uint16_t servoPos[NUM_SERVOS];

void main(void) {
OSCCON=0b01110000;      //8MHz
PLLEN=1;                //x4=32MHz
//setup 1mS interrupt = 8,000,000/16 = 500,000/10 = 50,000 set PR2=49 = 50,000/50 = 1000 = 1mS
T2CON=0b01001110;       //pre=16 post=10
PR2=49;
TMR2IE=1;               //timer 2 interrupts enable
T1CON=0;                //timer 1 stopped
for(uint8_t i=0;i<NUM_SERVOS;i++){
servoPos[i]=i*1000+8000; //1ms(8000) to 1.875(7/8ths - 15000)ms in 1/8th mS steps
}
TRISC=0b11111100;           //CCP0 & 1 output
PEIE=1;
GIE=1;
while(1){
}
}

void __interrupt() inter(void){
if(TMR2IE && TMR2IF){
ms++;
count++;
if(count>=20){          //start every 20mS
TMR1=0;             //zero timer 1
T1CON=1;            //start timer 1
count=0;
CCP1CON=0b1000;     //CCP1 pin low and high on match - will be first pulse
CCPR1L=0x0d;
CCPR1H=0x07;
CCP1IE=1;           //enable CCP1 interrupts
CCP1IF=0;           //ensure interrupt flag is clear
servoCount=0;       //reset servoCount
LATC0=1;            //connected to data in of shift register will clock in a high when CCP1 goes high
}
TMR2IF=0;
}
if(CCP1IE && CCP1IF){
LATC0=0;                //clear the data in pin
if(servoCount==9)       //have we done all servos?
CCP1IE=0;           //yes so no more CCP1 interrupts
if(CCP1CON==0b1000){    //have we started the 4000 cycle pulse
CCP1CON=0b1001;     //yes so end the pulse after 0.5mS
wordTemp=CCPR1H*256+CCPR1L;
wordTemp=wordTemp+4000;
CCPR1L=wordTemp & 255;
CCPR1H=wordTemp/256;
}else{
CCP1CON=0b1000;     //No so output the timed gap
wordTemp=CCPR1H*256+CCPR1L;
wordTemp=wordTemp-4000+servoPos[servoCount];
CCPR1L=wordTemp&255;
CCPR1H=wordTemp/256;
servoCount=servoCount+1;
}
CCP1IF=0;
}
}
The above is untested as I don't have the hardware but I think it works.

Mike.

#### Pommie

##### Well-Known Member
I took some timings from the C code using the MPLABX stopwatch and simulator,
This is what I found,
2024 (253 µs) start of process will start first pulse
3999 (499.875 µs) end of first pulse 0.5mS
4001 (500.125 µs) start of servo 2 pulse - servo 1 time 1mS
3999 (499.875 µs) finished after 0.5mS
5001 (625.125 µs) start of servo 3 pulse - servo 2 time 1.125mS
3999 (499.875 µs)
6001 (750.125 µs) start of servo 4 pulse - servo 3 time 1.25mS
3999 (499.875 µs)
6971 (871.375 µs) start of servo 5 pulse - servo 4 time 1.375mS
4029 (503.625 µs)
8001 (1.000125 ms) start of servo 6 pulse - servo 5 time 1.5mS
3969 (496.125 µs)
9031 (1.128875 ms) start of servo 7 pulse - servo 6 time 1.675mS
3999 (499.875 µs)
10001 (1.250125 ms) start of servo 8 pulse - servo 7 time 1.75mS
3999 (499.875 µs)
11001 (1.375125 ms) just filling in time 1.875mS
3999 (499.875 µs)
12001 (1.500125 ms) ditto 2mS
49969 (6.246125 ms) start of new 20mS frame

Total time appears to be 18mS - not sure why.

The times vary due to interrupt latency but are pretty consistent. The CCP1 output should be cycle accurate due to it being hardware timed.

Mike.

#### Pommie

##### Well-Known Member
The above times agree with the times set in the for loop
Code:
    for(uint8_t i=0;i<NUM_SERVOS;i++){
servoPos[i]=i*1000+8000; //1ms(8000) to 1.875(7/8ths - 15000)ms in 1/8th mS steps
}
Looking at the first servo, the times are,
3999 (499.875 µs) end of first pulse 0.5mS
4001 (500.125 µs) start of servo 2 pulse - servo 1 time 1mS

and 4001+3999 is 8000 as is in servoPos[0] or 1mS at 32MHz.

Mike.

#### camerart

##### Active Member
Hi M,
All fine, thanks.
I'll let you know.

Writing a description in AAC is an interesting exercise, as I have to understand it.

Trying again to understand the 1ms INTERRUPT.
1/ e,g, the GPS INTERRUPT fires externally and 'randomly', what happens if it fires at the same time a the 1ms SERVO INTERRUPT?

2/ The GPS INT fires and a BYTE starts to load into the PIC memory (behind the scenes in H/W?) 1/2 way loaded, the SERVO INT fires (In H/W and shifts the register) while the GPS is still loading. Next there's another GPS BYTE. Am I correct that the H/Ws works in parallel?
C

Last edited:

#### camerart

##### Active Member
Hi M,
As the SPI MOSI is on RC2, the RC PIN will need changed to RC1 sometime.
Is this a matter of changing all of the CCPR1 to CCPR2 etc?
C

#### jjw

##### Member
Hi M,
As the SPI MOSI is on RC2, the RC PIN will need changed to RC1 sometime.
Is this a matter of changing all of the CCPR1 to CCPR2 etc?
C
RC2 pin is for digital I/O or CCP1 (or FLTA interrupt), not for SPI.

#### camerart

##### Active Member
RC2 pin is for digital I/O or CCP1 (or FLTA interrupt), not for SPI.
Hi J,
Correct!
Thanks.
C

#### Pommie

##### Well-Known Member
Am I correct that the H/Ws works in parallel?
Yes, everything will do it's thing and when it's complete it sets it's interrupt flag and generates an interrupt. If while a byte (from RS232) is being loaded into memory a timer 2 interrupt occurs then it'll interrupt once the current interrupt has finished. As all these things are happening at 8,000,000 instructions per second then nothing gets missed. An interrupt routine would have to be over 500uS (4000 instructions) long for an interrupt to be missed.

Mike.

Replies
168
Views
7K
Replies
22
Views
1K
Replies
0
Views
473
Replies
3
Views
3K
Replies
0
Views
947