Servo control based on pulsin?

Hankinator

New Member
First time poster long time lurker.

I have a need to control a servo based on pulsin. Specifically I have a dirt bike with an electronic controlled powervalve. The CDI/Power valve controller are smoked and quite expensive to replace. I have the CDI coverd but need to build a power valve controller.

In a nut shell I need to read RPM of the engine then make a mechanical movement with a servo based on RPM.

I learned most everything from this thread: http://www.picaxeforum.co.uk/showthread.php?23897-Looking-for-a-DIY-Shift-Rev-Light-ideas

So I have it working a bit now but think it can be better. Code I am using is below...thanks to Goetex.

As you can see in my code I have position "step" based on RPM ranges. How can I ditch this code and convert to an incremental version?

Code:
'****************************
'* HB 3-6k             
'Pulse in period	RPM
'2000	3000
'1500	4000
'1200	5000
'1000	6000
'800	7500
'700	8571.428571
'600	10000
'****************************
#Picaxe 08M2
#No_data
#com 6  'change as required
#terminal 4800
setfreq M4 
pause 200 
        
symbol MARK = W1         
symbol SPACE = W2       
symbol Period = W3
'===========================================



init: servo 1,170  ; initialise servo ; move servo to one end....power valve is closed

MAIN:


  Pulsin C.4,1,MARK     'Measure Positive width
  Pulsin C.4,0,SPACE    'Measure Negative width
  
  LET PERIOD = MARK + SPACE  'Calculate Time period
 
  'Display Data 
  'sertxd ("MARK = ",#MARK,CR,LF)
  'sertxd ("SPACE = ",#SPACE,CR,LF)
  sertxd ("PERIOD = ",#PERIOD,CR,LF)
  sertxd (CR,LF)
  
  pause 200
  

IF PERIOD < 10000 AND PERIOD >=2000 then ; Check RPM..if 3k or less keep PV closed (servo at closed position 190?)
	servopos 1,170
	elseif PERIOD <1999 AND PERIOD >=1500 then  ;Open @ 4k RPM
	servopos 1,145
	elseif PERIOD <1499 AND PERIOD >=1000 then  ;Open @ 5k RPM
	servopos 1,105
	elseif PERIOD <999 AND PERIOD >=400 then	;Open @ 6k and avove RPM
	servopos 1,78
	'elseif PERIOD <449 then  ;open when off or stray.
	'servopos 1,78
	'elseif W3 <1399 AND W3 >=1250 then	;Open @ 7000 RPM
	'servopos 1,150
	'elseif W3 <1249 AND W3 >=100 then	;Open @ 7500 RPM
	'servopos 1,140
	'elseif W3 <=99 then 
	'servopos 1,190
	'elseif W1 >6000 then			;Full open 8500 and over 
	'servopos 0,225
	end if
	
	

goto MAIN:
Any ideas?

Thanks,

Hank
 

westaust55

Moderator
You could use the MIN and MAX math functions to pre define limits for the Period variable

Then scale the value to be in the range 75 to 255 or whatever range you end for the SERVO.
Eg (something like)
Servovalue = period - minperiod * servorange / periodrange + minservo
 

hippy

Technical Support
Staff member
As you can see in my code I have position "step" based on RPM ranges. How can I ditch this code and convert to an incremental version?
Welcome to the PICAXE Forum.

The first step in the process would be to detail what servo position you require for each RPM / PULSIN value.

If it's a linear translation then you can probably use simple scaling but if non-linear that may require more complexity.
 

MPep

Senior Member
You'll need to graph these numbers:
'Pulse in period RPM
'2000 3000
'1500 4000
'1200 5000
'1000 6000
'800 7500
'700 8571.428571
'600 10000
and follow Hippy's wisdom
If it's a linear translation then you can probably use simple scaling but if non-linear that may require more complexity.
 

Hankinator

New Member
All,

Thanks for the quick replies. At this time we can assume it's a linear movement. I know the MIN and MAX (170 closed, 78 completely open) and the RPM/Pulsein. Basically I want to begin opening @ 3k RPM and be fully open @ 6k RPM.

I am very green to coding. I guess I really don't understand the Increment commands and how to store, recall and incorporate into the code. Will it be fast enough? or at least as fast as my current code?

Any help or direction to a tutorial about servo position and increment?

Thanks,

Hankinator
 

westaust55

Moderator
In terms of speed, at 4 MHz clock speed (SETFREQ M4) each command takes around 250 usec but some a little more.
As a very rough guide consider your IF...THEN structure taking about 7 * 0.25 = ~2ms per program loop.

For a linear case with direct math translation as per my suggestion,
You have MIN, MAX, and a math calc with 4 functions finally a SetPos command so again you are looking very roughly at about 7 x 0.25 = ~2ms per program loop.

Not sure what/how you are trying to make the process "incremental"

If you start doing more maths, storing data, etc then the time to complete each program lop will increase.
If you wish to improve the response time then you could increase the clock speed (SETFREQ M16) but then will also affect the values from the PULSIN command. Note you cannot use the Servo commands on an M2 at other than 4 or 16 MHz.
 

AllyCat

Senior Member
Hi,

Firstly, I'm not sure if you've "sussed" the conversion from PULSEIN to RPM, but basically it's RPM = 6000000 / PULSEIN. Unfortunately PICaxe Basic can't handle a number as big as 6,000,000 , but you can "scale" the values without losing much accuracy, e.g.:
Code:
W3 = pulsein / 10
W3 = 60000 / W3
rpm = W3 * 10
The "increment" command simply adds '1' to a variable (i.e. INC b1 is exactly the same as b1 = b1 + 1) so is not really relevant to the calculation you then want to perform (particularly as you can't use MAX or MIN with INC).

The calculation could be done with MAX and MIN limits, but IMHO it's probably easiest to handle the "limit" cases with an IF ... ELSE structure, i.e.:
Code:
IF rpm < 3000 THEN
     pvcontrol = 170
ELSE IF
    rpm > 6000 THEN
     pvcontrol = 78
ELSE
..........
ENDIF
Then you just need to calculate the "linear" conversion between 3000 and 6000 rpm and pvcontrol 170 to 78. Thus 3000 (i.e. 6000 - 3000) "maps" to 92 (i.e. 170 - 78).

So first, subtract 3000 from the rpm, then multiply by 92 / 3000 and subtract that from 170. Unfortunately again, PICaxe maths cannot handle that directly; the simplest method is to pre-calculate 3000 / 92 (= 32.6) so the full conversion becomes W3 = rpm - 3000 : W3 = W3 / 32 : pvcontrol = 170 - W3 (not checked as it's getting late here).

Or a slightly more accurate method is to "split" the division by 3000. The largest number that PICaxe basic can handle is about 65,000 so you can't multiply 3000 by 92 (nor usefully divide 3000 by 3000 with integer maths) , so try W3 = W3 / 50 * 92 / 60 which should be slightly better than the W3 = W3 / 32. Or, rather less obvious is: W3 = W3 / 5 * 23 / 150

Cheers, Alan.
 
Top