PDA

View Full Version : Making code more efficient, any ideas please?



BobEdge
- 12th July 2011, 10:23
Hi,

I am writing a program to fire a six thyristor phase angle controlled bridge rectifier.
This is the sequence for forward rotation.

Fire thyristors 1 & 5, wait 60 degrees, fire 1 & 6, wait 60 degrees, fire 2 & 6, wait 60 degrees, fire 2 & 4, wait 60, fire 3 & 4, wait 60, fire 3 & 5.

There is a similar sequence for reverse, 1-6, 1-5, 2-4, 2-6, 3-5, 3-4.
Also each thyristor is given 5 pulses to make sure it has fired.

My code works fine, but it is very linear, and takes alot of code space.


weldingfwd: 'welding routine for forward phase rotation
if badweld = 1 then noweld
pauseus thirtydeg
pauseus angletime 'pause for required delay time
low thy1 'fire first pair of thyristors
low thy2
pauseus 200
high thy1
high thy2
pauseus 200
low thy1
low thy2
pauseus 200
high thy1
high thy2
pauseus 200
low thy1
low thy2
pauseus 200
high thy1
high thy2
pauseus 200
low thy1
low thy2
pauseus 200
high thy1
high thy2
pauseus 200
low thy1
low thy2
pauseus 200
high thy1
high thy2
temp = sixtydeg - 1800 ' take time firing thyristors from sixtydeg time
pauseus temp ' and pause for required time
low thy1 'then fire second pair
low thy3
pauseus 200
high thy1
high thy3
pauseus 200
low thy1
low thy3
pauseus 200
high thy1
high thy3
pauseus 200
low thy1
low thy3
pauseus 200
high thy1
high thy3
pauseus 200
low thy1
low thy3
pauseus 200
high thy1
high thy3
pauseus 200
low thy1
low thy3
pauseus 200
high thy1
high thy3
returnThe above is the code for firing the first two in the sequence of six, for forwards rotation. To fire all six, for both forward, and reverse will take six times as much code.
I am using interrupts (Thanks Darrel) to start the firing sequence. INT0 to be precise.
I was wondering if anyone has any ideas to make the code more efficient, and elegant?
A freind suggested using capture compare, but I am struggling to find any basic information on the concepts of how CCP works.

Kind regards
Bob...

sayzer
- 12th July 2011, 13:16
Having all sequences stored in eeprom and reading them from there would make it much shorter.

for example:



read Index,PosX ' Read all sequences from eeprom, previously arranged manually.
Read (Index+100),PauseVal ' Read required delay time stored in eeprom (in case the delay time is different for each sequence).
Thy1 = PosX.0 ' Assign thyristor distribution.
Thy2 = PosX.1
Thy3 = PosX.2
Thy4 = PosX.3
Thy5 = PosX.4
Thy6 = PosX.5
pauseus PauseVal ' Delay for required time.
index = index + 1 ' Increment the sequence index.
if index = ENDOFSEQ then index = 0 ' Reached the end of sequence. Loop over.



This is just an example.
You may change it as you like.
Just have all on-off sequence and delay time(s) stored in eeprom and read from there.

HenrikOlsson
- 12th July 2011, 13:35
Hi Bob,

(EDIT: sayzer beat me to it but I'll post this anyway)

Several ideas....but they depend a bit on how you have the thyristors connected to the PIC. The "best" would be if they where connected to consecutive pins on a port, like PortC.0 to PortC.5 or PortB.2 to PortB.7 etc.

Without knowing that, here's one way. Create an index variable or "pointer" if you like that you cycle thru 0,1,2,3,4,5 or 5,4,3,2,1,0 depending on direction. Then use a SELECT CASE statement with your index variable and 6 different cases, all quite similar to each other but with the different thyristors firing. But use a FOR-NEXT loop instead of 5 discrete on-off pulse cycles. Something like this:

Index VAR BYTE
Fire VAR BYTE
Direction VAR BYTE
Forward CON 1
Reverse CON 255

Direction = Forward

Select Case Index

Case 0
For Fire = 0 to 4
High Thy1
High ThY5
PauseUs 200
Low Thy1
Low Thy5
PauseUs 200
NEXT
Index = Index + Direction
If Index = 255 then Index = 5 ' We're going backwards, start over at step 5

Case 1
For Fire = 0 to 4
High Thy1
High Thy6
PauseUs 200
Low Thy1
Low Thy6
PauseUs 200
Next
Index = Index + Direction

' Case 2,3 and 4 all similar to Case 1

Case 5
For Fire = 0 to 4
High Thy3
High Thy5
PauseUs 200
Low Thy3
Low Thy5
PauseUs 200
Next
Index = Index + Direction
If Index = 6 then Index = 0 ' We're going forward, start over at step 0

END SELECT
All untested code but I hope it can serve as a starting point. If you do have the thyrsitor across a single port then a lookup table and a single FOR-NEXT loop can replace the above.

HTH,
/Henrik.

Bruce
- 12th July 2011, 14:12
Which PIC type are you using?

If you're using a newer enhanced core type 16F or 18F, and have Thy1, Thy2, etc aliased to LAT registers, then HIGH Thy1, HIGH Thy2, etc will work. If you're using an older 16F part this may cause you some grief due to read-modify-write.

Both above options sound good, but there are potential R-M-W issues depending on which PIC you're using, and how you have aliased your SCR control pins.

mister_e
- 12th July 2011, 17:35
Like Bruce said, be careful when using successive High/Lows on adjacent pins. If they're not adjacent, maybe you could find some interesting of DT Virtual Port?

A Lookup table in codespace or EEPROM is probably the mosty efficient solution.

keithdoxey
- 12th July 2011, 22:12
Fire thyristors 1 & 5, wait 60 degrees, fire 1 & 6, wait 60 degrees, fire 2 & 6, wait 60 degrees, fire 2 & 4, wait 60, fire 3 & 4, wait 60, fire 3 & 5.

There is a similar sequence for reverse, 1-6, 1-5, 2-4, 2-6, 3-5, 3-4.
Also each thyristor is given 5 pulses to make sure it has fired.



How about a different approach...... sort of in pseudo code as I havent touched PicBasic for about 3 years and am a tad rusty to say the least !!!

If all the thyristors are on the same port, and you always need to fire two of the 6 at any time, then assuming 1-6 are connected to port.0 to port.5 repectively, you could write to the whole port in one hit

FwdStep 1 00010001 = 11H (Thys 5 + 1) = 17
FwdStep 2 00100001 = 21H (Thys 6 + 1) = 33
FwdStep 3 00100010 = 22H (Thys 6 + 2) = 34
FwdStep 4 00001010 = 0AH (Thys 4 + 2) = 10
FwdStep 5 00001100 = 0CH (Thys 4 + 3) = 12
FwdStep 6 00010100 = 14H (Thys 5 + 3) = 20

RevStep 1 00100001 = 21H (Thys 6 + 1) = 33
RevStep 2 00010001 = 11H (Thys 5 + 1) = 17
RevStep 3 00001010 = 0AH (Thys 4 + 2) = 10
RevStep 4 00100010 = 22H (Thys 6 + 2) = 34
RevStep 5 00010100 = 14H (Thys 5 + 3) = 20
RevStep 6 00001100 = 0CH (Thys 4 + 3) = 12

All thyristors off = 00000000 = 00H = 0

All you would need would be two arrays to hold the ON values for driving the thyristors

Forward 17,33,34,10,12,20
Reverse 33,17,10,34,20,12

Read the value for the current step and store it in a variable "portvalue" then a short loop to send the fire pulses

For Fire = 0 to 4
Port = portvalue ' set the respective pins high
pauseus 200
Port = 0 ' set all the pins low
pauseus 200
Next

get the next value from the array and repeat

This method also ensures that the 4 unused thyristors dont get a fire pulse.


Hopefully I understood what you want to do and that you understand what I am trying to say LOL

BobEdge
- 26th July 2011, 13:28
Hi,

Thank you all for your replies. This gives me something to work on.

Regards
Bob.