Dear all,
Here is the last bit of code of my line-follower program that looks bulky compared to other pieces now. This is used to 'calibrate' the exposure time for photodiode array to different light conditions. As for testing, I'm running it only once at the start of the program and that is sufficient because lighting conditions do not change. In real life application, however, I would have to run it more often than that, so being able to run it as fast as possible is important.
One obvious optimisation is decreasing the number of pixels I read the value of - probably reading 16 pixels or every 8th pixel and then averaging those would be as good as averaging all 128. But I would have to run clock all 128 times anyway, so I'm not sure how to achieve any real speed improvements with that.
The second challenging area is the long select ... case statement with two's complement mathematics. I have a suspicion some OR binary operation could be quicker, but not there yet to figure it out. I will be working with this project tonight and some time tomorrow, so ideas and directions welcome, I will try them out and report back. And also post if come up with something myself while posting this .
Thank you for your time,
Edmunds
Here is the last bit of code of my line-follower program that looks bulky compared to other pieces now. This is used to 'calibrate' the exposure time for photodiode array to different light conditions. As for testing, I'm running it only once at the start of the program and that is sufficient because lighting conditions do not change. In real life application, however, I would have to run it more often than that, so being able to run it as fast as possible is important.
One obvious optimisation is decreasing the number of pixels I read the value of - probably reading 16 pixels or every 8th pixel and then averaging those would be as good as averaging all 128. But I would have to run clock all 128 times anyway, so I'm not sure how to achieve any real speed improvements with that.
The second challenging area is the long select ... case statement with two's complement mathematics. I have a suspicion some OR binary operation could be quicker, but not there yet to figure it out. I will be working with this project tonight and some time tomorrow, so ideas and directions welcome, I will try them out and report back. And also post if come up with something myself while posting this .
Code:
'Byte variables
Symbol pixel_data = b4 'Data from sensor [memory for testing]
Symbol pixel_mask = b5 'Decoded 8 pixel data
Symbol line_edge = b6 'Rightmost edge of the line
Symbol line_width = b7 'Width of the line in 16th of the total width
Symbol line_pos = b8 'Position of the line centre with 16 position resolution
Symbol counter2 = b9 'Just a counter, #2
'Word variables
Symbol Tint = w27 'Integration time adjustable part
Symbol Vout = w26 'Voltage on AO pin
Symbol EVout = w25 'Voltage on AO pin error, deviation from Vtarget
Symbol ELine = w24 'Line position error
Symbol Counter = w23 'Just a counter, #1
Symbol line_state = w22 'Sensor output, normalized to fit into 16bit word
'Constants
Symbol Vtarget = 198 'Target voltage on AO pin, two's complement, so actually 70
Symbol KpEVout = 30 'P coefficient/multiplier for Vout error correction
Symbol KpELine = 50 'P coefficient/multiplier for line position error correction, 10 means 1
Cal_exposure:
do 'Big calibration loop, exit only when Vout is good
high SI : pulsout CLK, 10 : low SI 'Pulse SI to end the scan/start the next scan
pwmout CLK, 1, 4 'Clock out some fast pulses (8MHz @ 64MHz clock speed
pauseus Tint 'Allow for sufficient integration time
pwmout CLK, OFF 'Stop the clock
high SI : pulsout CLK, 10 : low SI 'Pulse SI to end the scan/start the next scan
Vout = 0 'Make Vout zero for a new cycle
for counter = 0 to 127 'Read 128 pixels ...
readadc 10, pixel_data '... with 8 bit ADC ...
pulsout CLK, 10 '... pulse the clock as fast as possible to read the next pixel ...
Vout = Vout + pixel_data '... add to Vout for average calculation later on ...
next counter '... continue until done with all pixels
Vout = Vout / 128 'Average value first
Vout = Vout max 127 'Limit to 127, not interested in near saturation region
EVout = Vtarget - Vout 'Vtarget is expressed in two's complenet to get a signed value
select case EVout 'Go to normal from two's complement numbers
case 128 : EVout = 0 '128 means 0
case < 128 'Means a negative number
EVout = 128 - EVout 'Get the magnitude of error
Evout = EVout * KpEVout / 10 'Calculate correction signal
if Tint > EVout then 'Prevet overflow below zero
Tint = Tint - EVout 'Correct integration time with the correction signal
else
Tint = 0
gosub Too_dark
endif
case > 128 'Means a positive number
EVout = EVout - 128 'Get the magnitude of error
Evout = EVout * KpEVout / 10 'Calculate correction signal
if Tint < 2600 then 'Prevet overflow to values that give saturation - might have to correct if read_data can be speeded up.
Tint = Tint + EVout 'Correct integration time with the correction signal
else
Tint = 2600
gosub Too_bright
endif
endselect
loop until EVout < 3 'Set error corridor here
return
Edmunds