Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Hardware ESC 8xSERVO CONTROL on PIC (Oshonsoft BASIC)

Status
Not open for further replies.
And what? As I said in $444,
The instruction I'm not sure of is,
CCP1CON=CCP1CON XOR 1
This should toggle bit zero of CCP1CON

Mike.
Edit, you may be able to use Toggle CCP1CON.0

Mike.
Hi M or S?
In #445, my tests of the suggested lines are shown. as: The tests that don't work '<<<<<<<<<
The tests that work, have been commented in to pruduce the result.

The CCP1CON=CCP1CON XOR 1 line, was not marked by '<<<<< by accident.
C
 
I don't understand the ON INTERRUPT error, but this CODE will be added to larger CODE, where a GPS INTERRUPT will be, which could be LOW INTERRUPT, so this is why I chose it.
Why, the code will work fine without any priority. The background code ( which currently does nothing) can do what it needs to. Why is it an error when the manual says it's correct?

Mike.
 
Why, the code will work fine without any priority. The background code ( which currently does nothing) can do what it needs to. Why is it an error when the manual says it's correct?

Mike.
Hi M,
An oshonsoft mystery!
I even tried the examples, and they showed the INTERRUPT error.
EDIT: I wonder if we're mixing HW with OSH SW?
Here is a section about saving, could [RCON.IPEN] plus [SAVE SYSTEM] be the alternative to the Error?
C
 

Attachments

  • Save system.jpg
    Save system.jpg
    63.4 KB · Views: 138
Last edited:
Hi M,
Should RCON.IPEN be included?
C
 

Attachments

  • IPEN.jpg
    IPEN.jpg
    193.5 KB · Views: 150
Last edited:
I've been thinking and as the 1kHz program worked well, why not do everything without interrupts?
As we're not sure what Oshonsoft is doing with Interrupts, here's a CCP1 only version without interrupts,
Code:
'18F4431 32MHz XTL REMOTE_SLAVE 164 389 030223 1200
Define CONFIG1L = 0x00
Define CONFIG1H = 0x06  '8mHz XTL x4 =32mHz
Define CONFIG2L = 0x0c
Define CONFIG2H = 0x20
Define CONFIG3L = 0x04
Define CONFIG3H = 0x80
Define CONFIG4L = 0x80  'Set for HVP
Define CONFIG4H = 0x00
Define CONFIG5L = 0x0f
Define CONFIG5H = 0xc0
Define CONFIG6L = 0x0f
Define CONFIG6H = 0xe0
Define CONFIG7L = 0x0f
Define CONFIG7H = 0x40

Define CLOCK_FREQUENCY = 32

'Define SIMULATION_WAITMS_VALUE = 1  'Comment in for SIM out for PIC

Dim servoCount as byte
Dim i as byte
Dim wordTemp As Word
Dim servoPos(8) as word
Dim frame as word

'need to ensure the 164 is reset at power on.

OSCCON = %01110000  '& h70
TRISA = %11000000   '7=OSC, 6=OSC,
TRISC = %11111010   '6=1-slave4431_cs, 2=74HC164 CLK, 0=74HC164 DATA
For i = 0 to 7
  servoPos(i)=i*250+2000    '1ms(2000) to 1.875(1 7/8ths - 3750)ms in 1/8th mS steps
Next i
TRISC=0b11111010            'CCP0 (RC2) & RC0 output
servoCount=8                'cause it to reset
T1CON=0b00100000            'prescaler = 4
T1CON.0=1                   'start timer
CCP1CON=0b1000              'will go high on interrupt - will start a 0.5mS pulse
frame=1000                  'start everything in 4000 cycles
While 1
  If PIR1.CCP1IF Then       'has CCP1 triggered?
    wordtemp.HB = CCPR1H    'get value of CCPR1 into wordTemp
    wordtemp.LB = CCPR1L
    If CCP1CON = 0x08 Then  'have we started the 1000 cycle pulse
      CCP1CON = 0x09        'yes so end the pulse after 0.5mS
      wordtemp = wordtemp + 1000  'adding 1000 will make pulse 0.5mS long
    Else
      LATC.0=0              'clear the data pin
      CCP1CON = 0x08        'No so output the timed gap
      if servoCount<8 then
        'still doing the servos so add remainder of time
        wordtemp = wordtemp+servoPos(servoCount)
        wordTemp=wordTemp-1000    'knock of the 1000 already elapsed
        frame=frame-servoPos(servoCount)
        servoCount = servoCount + 1
      Else
        'done all the servos so just the frame gap to do
        wordtemp = wordtemp +frame
        frame=31000         '40,000(20mS) minus time of positive pulse(0.5mS)
        servoCount=0        'start all over again
        LATC.0=1            'will become first pulse
      Endif
    Endif
    CCPR1H = wordtemp.HB    'put value back into CCPR1
    CCPR1L = wordtemp.LB
    PIR1.CCP1IF = 0         'clear interrupt flag
  Endif
  'change any servo positions here
Wend
End

Hopefully, this will work and then the UART stuff can be added the same way (without interrupts).

Another thing to consider is resetting the 164 at powerup either with a spare pic pin of an RC reset circuit or it could be done in software.

Also attached is the C file.

Mike.
 

Attachments

  • No_ISR.c
    1.6 KB · Views: 144
These are the times I get if I put a breakpoint on the line
wordTemp=CCPR1;
or in Oshonsoft,
wordtemp.HB = CCPR1H

Target halted. Stopwatch cycle count = 4001 (500.125 µs)
Target halted. Stopwatch cycle count = 3998 (499.75 µs)
Target halted. Stopwatch cycle count = 4001 (500.125 µs)
Target halted. Stopwatch cycle count = 5003 (625.375 µs)
Target halted. Stopwatch cycle count = 3996 (499.5 µs)
Target halted. Stopwatch cycle count = 6003 (750.375 µs)
Target halted. Stopwatch cycle count = 4001 (500.125 µs)
Target halted. Stopwatch cycle count = 6998 (874.75 µs)
Target halted. Stopwatch cycle count = 4001 (500.125 µs)
Target halted. Stopwatch cycle count = 7998 (999.75 µs)
Target halted. Stopwatch cycle count = 4001 (500.125 µs)
Target halted. Stopwatch cycle count = 8998 (1.12475 ms)
Target halted. Stopwatch cycle count = 4001 (500.125 µs)
Target halted. Stopwatch cycle count = 10003 (1.250375 ms)
Target halted. Stopwatch cycle count = 3996 (499.5 µs)
Target halted. Stopwatch cycle count = 11003 (1.375375 ms)
Target halted. Stopwatch cycle count = 4001 (500.125 µs)
Target halted. Stopwatch cycle count = 63998 (7.99975 ms)

These times represent the 8 servos varying from 1mS (first two times) and 1.875mS and the final long gap (8.5mS).

If you add all those times together they add up to 20mS.

Mike.
 
I've been thinking and as the 1kHz program worked well, why not do everything without interrupts?
As we're not sure what Oshonsoft is doing with Interrupts, here's a CCP1 only version without interrupts,
Code:
'18F4431 32MHz XTL REMOTE_SLAVE 164 389 030223 1200
Define CONFIG1L = 0x00
Define CONFIG1H = 0x06  '8mHz XTL x4 =32mHz
Define CONFIG2L = 0x0c
Define CONFIG2H = 0x20
Define CONFIG3L = 0x04
Define CONFIG3H = 0x80
Define CONFIG4L = 0x80  'Set for HVP
Define CONFIG4H = 0x00
Define CONFIG5L = 0x0f
Define CONFIG5H = 0xc0
Define CONFIG6L = 0x0f
Define CONFIG6H = 0xe0
Define CONFIG7L = 0x0f
Define CONFIG7H = 0x40

Define CLOCK_FREQUENCY = 32

'Define SIMULATION_WAITMS_VALUE = 1  'Comment in for SIM out for PIC

Dim servoCount as byte
Dim i as byte
Dim wordTemp As Word
Dim servoPos(8) as word
Dim frame as word

'need to ensure the 164 is reset at power on.

OSCCON = %01110000  '& h70
TRISA = %11000000   '7=OSC, 6=OSC,
TRISC = %11111010   '6=1-slave4431_cs, 2=74HC164 CLK, 0=74HC164 DATA
For i = 0 to 7
  servoPos(i)=i*250+2000    '1ms(2000) to 1.875(1 7/8ths - 3750)ms in 1/8th mS steps
Next i
TRISC=0b11111010            'CCP0 (RC2) & RC0 output
servoCount=8                'cause it to reset
T1CON=0b00100000            'prescaler = 4
T1CON.0=1                   'start timer
CCP1CON=0b1000              'will go high on interrupt - will start a 0.5mS pulse
frame=1000                  'start everything in 4000 cycles
While 1
  If PIR1.CCP1IF Then       'has CCP1 triggered?
    wordtemp.HB = CCPR1H    'get value of CCPR1 into wordTemp
    wordtemp.LB = CCPR1L
    If CCP1CON = 0x08 Then  'have we started the 1000 cycle pulse
      CCP1CON = 0x09        'yes so end the pulse after 0.5mS
      wordtemp = wordtemp + 1000  'adding 1000 will make pulse 0.5mS long
    Else
      LATC.0=0              'clear the data pin
      CCP1CON = 0x08        'No so output the timed gap
      if servoCount<8 then
        'still doing the servos so add remainder of time
        wordtemp = wordtemp+servoPos(servoCount)
        wordTemp=wordTemp-1000    'knock of the 1000 already elapsed
        frame=frame-servoPos(servoCount)
        servoCount = servoCount + 1
      Else
        'done all the servos so just the frame gap to do
        wordtemp = wordtemp +frame
        frame=31000         '40,000(20mS) minus time of positive pulse(0.5mS)
        servoCount=0        'start all over again
        LATC.0=1            'will become first pulse
      Endif
    Endif
    CCPR1H = wordtemp.HB    'put value back into CCPR1
    CCPR1L = wordtemp.LB
    PIR1.CCP1IF = 0         'clear interrupt flag
  Endif
  'change any servo positions here
Wend
End

Hopefully, this will work and then the UART stuff can be added the same way (without interrupts).

Another thing to consider is resetting the 164 at powerup either with a spare pic pin of an RC reset circuit or it could be done in software.

Also attached is the C file.

Mike.
Hi M,
Quick test, no reset, back to bed.
C
 

Attachments

  • No Interrupt.jpg
    No Interrupt.jpg
    140.2 KB · Views: 138
That looks very promising.

Mike.
Hi M,
I've been thinking and as the 1kHz program worked well, why not do everything without interrupts?
As we're not sure what Oshonsoft is doing with Interrupts, here's a CCP1 only version without interrupts,
Code:
'18F4431 32MHz XTL REMOTE_SLAVE 164 389 030223 1200
Define CONFIG1L = 0x00
Define CONFIG1H = 0x06  '8mHz XTL x4 =32mHz
Define CONFIG2L = 0x0c
Define CONFIG2H = 0x20
Define CONFIG3L = 0x04
Define CONFIG3H = 0x80
Define CONFIG4L = 0x80  'Set for HVP
Define CONFIG4H = 0x00
Define CONFIG5L = 0x0f
Define CONFIG5H = 0xc0
Define CONFIG6L = 0x0f
Define CONFIG6H = 0xe0
Define CONFIG7L = 0x0f
Define CONFIG7H = 0x40

Define CLOCK_FREQUENCY = 32

'Define SIMULATION_WAITMS_VALUE = 1  'Comment in for SIM out for PIC

Dim servoCount as byte
Dim i as byte
Dim wordTemp As Word
Dim servoPos(8) as word
Dim frame as word

'need to ensure the 164 is reset at power on.

OSCCON = %01110000  '& h70
TRISA = %11000000   '7=OSC, 6=OSC,
TRISC = %11111010   '6=1-slave4431_cs, 2=74HC164 CLK, 0=74HC164 DATA
For i = 0 to 7
  servoPos(i)=i*250+2000    '1ms(2000) to 1.875(1 7/8ths - 3750)ms in 1/8th mS steps
Next i
TRISC=0b11111010            'CCP0 (RC2) & RC0 output
servoCount=8                'cause it to reset
T1CON=0b00100000            'prescaler = 4
T1CON.0=1                   'start timer
CCP1CON=0b1000              'will go high on interrupt - will start a 0.5mS pulse
frame=1000                  'start everything in 4000 cycles
While 1
  If PIR1.CCP1IF Then       'has CCP1 triggered?
    wordtemp.HB = CCPR1H    'get value of CCPR1 into wordTemp
    wordtemp.LB = CCPR1L
    If CCP1CON = 0x08 Then  'have we started the 1000 cycle pulse
      CCP1CON = 0x09        'yes so end the pulse after 0.5mS
      wordtemp = wordtemp + 1000  'adding 1000 will make pulse 0.5mS long
    Else
      LATC.0=0              'clear the data pin
      CCP1CON = 0x08        'No so output the timed gap
      if servoCount<8 then
        'still doing the servos so add remainder of time
        wordtemp = wordtemp+servoPos(servoCount)
        wordTemp=wordTemp-1000    'knock of the 1000 already elapsed
        frame=frame-servoPos(servoCount)
        servoCount = servoCount + 1
      Else
        'done all the servos so just the frame gap to do
        wordtemp = wordtemp +frame
        frame=31000         '40,000(20mS) minus time of positive pulse(0.5mS)
        servoCount=0        'start all over again
        LATC.0=1            'will become first pulse
      Endif
    Endif
    CCPR1H = wordtemp.HB    'put value back into CCPR1
    CCPR1L = wordtemp.LB
    PIR1.CCP1IF = 0         'clear interrupt flag
  Endif
  'change any servo positions here
Wend
End

Hopefully, this will work and then the UART stuff can be added the same way (without interrupts).

Another thing to consider is resetting the 164 at powerup either with a spare pic pin of an RC reset circuit or it could be done in software.

Also attached is the C file.

Mike.
Hi M,
Interesting!
I'm finding it difficult to understand INTERRUPTS!

It appears that the Osh ON HIGH INTERRUPT, sets the GIE, RCON, and the setting from the D/S which is (I think) a HW INTERRUPT? So with CCPR, we still have an INTERRUPT.

Regarding WEND and WHILE, is this the same as my previous MAIN_LOOP and GOTO MAIN_LOOP, so I can write a control program there?
C
 
No need to understand interrupts as we're no longer using them. I don't know what Osh does with them so it's better to not use them.
So with CCPR, we still have an INTERRUPT.
Nope, we definitely don't have any interrupts. No on anything interrupt wise.

A while 1 statement loops forever so it'll never get out of that loop so no need for any GOTOs either.

BTW, the code in the loop is very rarely executed and probably uses less than 1% of the processor time so lot's of time left.

Let me know what "control program" you want to write.

Mike.
 
No need to understand interrupts as we're no longer using them. I don't know what Osh does with them so it's better to not use them.

Nope, we definitely don't have any interrupts. No on anything interrupt wise.

A while 1 statement loops forever so it'll never get out of that loop so no need for any GOTOs either.

BTW, the code in the loop is very rarely executed and probably uses less than 1% of the processor time so lot's of time left.

Let me know what "control program" you want to write.

Mike.
Hi M,
As you can see it's working on the HW, but it no longer works on the simulator.
It's good for me to look at the sim, but it doesn't matter really.

I've been working on this for about 5 years. There are 2x things to finish before the control section, SERVOS and some SPI between 2x PICs, my mate is working on the SPI.
Once we have the SERVOS and SPI working, next comes the exciting bit of getting the thing to fly. So leave this until we've all finished, and I'll include you in the RC process. Really looking forward to it.

In your CODE where will the RC section go?
C
 
The logic trace looks correct but I don't understand why channel 5 is 1.122 mS when it should be 1.25mS.

I'm assuming channel 1 is the CCP1 output and that looks good. Can you check the timings of the pulses?

Each positive pulse should be 0.5mS long and the zero part should be the rest so servo 0 is 500uS, servo 1 is 625uS servo 2 is 750uS etc. This would give a time for servo 2 of 1.25mS (500+750uS) as noted in the first sentence.

Mike.
 
In your CODE where will the RC section go?
In the code the RC section doesn't exist, the UART code can go in the While 1 loop and get a sentence, parse that sentence and then adjust the servos as needed.

What is the RC section?

Mike.
BTW, I still believe you only need one pic for this project and a second one will just cause problems.
 
In the code the RC section doesn't exist, the UART code can go in the While 1 loop and get a sentence, parse that sentence and then adjust the servos as needed.

What is the RC section?

Mike.
BTW, I still believe you only need one pic for this project and a second one will just cause problems.
Hi M,
The SERVO part that we are working on is the last PERPHERALS of a long project.
If you look on this forum for my posts you'll find it also on AAC.

There are 2x PICs on 2x modules, where all 4x PICs 'talk' to each other.

Once all of the peripherals are happy talking, we can start on the RC section. So on each PIC there is CODE for it's part in the project. This PIC controls the MOTORS?SERVOS once it receives a message from the system, so there is no RC section, but where will it go in this CODE?

I'm trying to sedn you the Analyser output so you can check anyhting.
C
 
To try to explain it further, the while loop normally does nothing and then about once every 4000 instructions it executes code which takes about 30 instructions. So it's basically idling and can do lots more, like reading the UART. Even doing all of that it'll probably still be less that 1%(2%?) of the processor time.

Mike.
 
To try to explain it further, the while loop normally does nothing and then about once every 4000 instructions it executes code which takes about 30 instructions. So it's basically idling and can do lots more, like reading the UART. Even doing all of that it'll probably still be less that 1%(2%?) of the processor time.

Mike.
Hi M,
OK, the SERVO and the UART will use APP 2% of the processor, that's good.

So once we have all of this working, there will be RC CODE written to actually control the SERVOS, I am asking where will that go in or around your CODE in the other 98% of time?

I've emailed the analyser DATA
C
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top