analog input to pwm frequency out.

Satchid

Member
Hi,

I need to feed a pulse stream to a stepper motor controller. But I need to make the pwm frequency variable with a potentiometer at an analog input on the 08m2 picaxe.

I am searching the net and this forum, and I am continuously finding to change the duty cycle.

But as I said, I need the frequency to change by changing the analog input. The duty cycle could stay within limits of say 40 to 60%

Here is the command for 10000Hz: pwmout C.2, 99, 199 ; 10000Hz at 50% @ 4MHz

and for the 500 Hz it is pwmout pwmdiv16, C.2, 124, 249 ; 500Hz at 50% @ 4MHz

Thank you for shedding some light on this bearing in mind that I am not a regular programmer

Willy
 

rossko57

Senior Member
You might be searching for the wrong things. PWM, varying the duty cycle, is usually used to control speed of an ordinary DC motor. You say you have a stepper motor, you'll be wanting to vary step rate instead.
Picaxe PWM can be used to generate pulses for a stepper, as it is convenient source of repeating pulses, but the "WM" (width modulation) isn't of much help.
Example discussion
http://www.picaxeforum.co.uk/archive/index.php/t-15591.html
 

erco

Senior Member
Edit: OK, I re-read and see that you are using a stepper motor controller. You're really close then. :)

Are you sure an 08M2 has enough I/O pins for your purpose? Many steppers require 4 PICAXE output pins, plus you need an ADC input to read your pot. An 08M2 only has ADCs on the 3 GPIO pins C.1, C.2 and C.4, which you need for controlling your stepper. You might consider a 14M2.

An 08M2 could be used to control your stepper if you want to use an IR remote, though. An IR receiver can easily connect to input-only C.3, and you can use C.0 (serial out) as your fourth output pin.

Alternatively, an 08M2 could also control your stepper by receiving serial data through pins C.5 or C.3.
 

hippy

Ex-Staff (retired)
A common way way to drive a stepper is with something like ...

Code:
dirsB = $FF
Do
  Lookup b0, ( %0011, %0110, %1100, %1001 ), pinsB
  b0 = b0 + 1 & 3
  Pause 100
Loop
Simply use a variable in the PAUSE and determine what value that variable should be for an ADC input value.
 

oracacle

Senior Member
How are you driving the motor. 10khz seems a little on the fast side unless the driver and motor is specified for running that fast
 

Satchid

Member
Thank you all,
Hippy, your code works, but the motor is to slow, even with a pause of 0.
I see that it is very dificult to do wath I want, Then I wil try working with a rotary switch instead. Every contact of the switch is then an other frequency. I need to use an other picaxe with more inputs.
Thank you al.
Willy
 

hippy

Ex-Staff (retired)
Hippy, your code works, but the motor is to slow, even with a pause of 0.
You can try running the PICAXE at a higher operating frequency; you can take the 08M2 up to 32MHz which is eight times faster than default 4MHz.

You can also replace the LOOKUP with a READ from EEPROM. Not sure exactly how fast that would be. It may not be useful here but could be useful for others.

Code:
#Picaxe 08M2

Eeprom 0,( 0 )

SetFreq M32

Read 0,b0
If b0 = 0 Then
  Do
    Write b0, %0011 : b0 = b0 + 1
    Write b0, %0110 : b0 = b0 + 1
    Write b0, %1100 : b0 = b0 + 1
    Write b0, %1001 : b0 = b0 + 1
  Loop Until b0 = 0
End If

dirsB = $FF
Do
  Read b0, pinsB
  b0 = b0 + 1
Loop
It might even be possible to increase that using 'bPtr', untested ...

Code:
#Picaxe 08M2

SetFreq M32

bPtr = 0
Do
  @bPtrInc = %0011
  @bPtrInc = %0110
  @bPtrInc = %1100
  @bPtrInc = %1001
Loop Until bPtr = 0

dirsB = $FF
Do
  pinsB = @bPtrInc
Loop
You haven't really explained what you need or are doing. I was assuming you wanted to adjust the step rate of the stepper motor but I may have misinterpreted that.
 

Satchid

Member
I need have a cloth of 7m long and 1.5m wide. I need to move this at 4m per hour. The mechanisme I am making. the motir has a reduction of 1:25 and there is an other reduction in the belts of 1:2. This means that i have to send 850HZ to the motorcontroller. That works. But for cleaning and maintenance purposes I want this wall to move faster to the speed that the worker find convenient. Until now the stepper worked at 10Khz. That would be the max speed.
I am loocking for a solution.

I tried allso the folowing, but did not played alot with it. It is not working, I can not regulate the speed. I gues that I am not doing the if comand right. I made it first without the pause 50 and now ith the pause 50. I ma using an picaxe 08m2 with a 5k om pot on c4. Output is c2

I started of wth logicar for the sintaxes.

What I am trying to do is the following:
Reard the analog port and if the reading is between 2 limits, then execute a preset pwmout. if the reading of the naalog port is not bteween the limits, then go and look furter to the next lower and higher limit. if it is correct, the do the appropriate pwmout, othewise go further etc.



symbol varA = b0
symbol varB = b1
symbol varC = b2
symbol varD = b3
symbol varE = b4
symbol varF = b5
symbol varG = b6
symbol varH = b7
symbol varI = b8
symbol varJ = b9
symbol varK = b10
symbol varL = b11
symbol varM = b12
symbol varN = b13
symbol varO = b14
symbol varP = b15
symbol varQ = b16
symbol varR = b17
symbol varS = b18
symbol varT = b19
symbol varU = b20
symbol varV = b21
symbol varTEMPBYTE1 = b22
symbol varTEMPBYTE2 = b23
symbol varTEMPBYTE3 = b24
symbol varTEMPBYTE4 = b25
symbol varTEMPBYTE5 = b26
symbol varTEMPBYTE6 = b27
symbol varTEMPWORD1 = w11
symbol varTEMPWORD2 = w12
symbol varTEMPWORD3 = w13
}


main:
let dirsC = 5


startreading:
readadc C.4, varTEMPBYTE1
if varTEMPBYTE1 >= 0 and varTEMPBYTE1 <= 25 then
pwmout pwmdiv16, C.2, 124, 249 ; 500Hz at 50% @ 4MHz
end if
pause 50
readadc C.4, varTEMPBYTE1
if varTEMPBYTE1 >= 25 and varTEMPBYTE1 <= 50 then
pwmout pwmdiv4, C.2, 249, 499 ; 1000Hz at 50% @ 4MHz
end if
pause 50
readadc C.4, varTEMPBYTE1
if varTEMPBYTE1 >= 50 and varTEMPBYTE1 <= 75 then
pwmout pwmdiv4, C.2, 124, 249 ; 2000Hz at 50% @ 4MHz
end if
pause 50
readadc C.4, varTEMPBYTE1
if varTEMPBYTE1 >= 75 and varTEMPBYTE1 <= 100 then
pwmout pwmdiv4, C.2, 82, 165 ; 3000Hz at 50% @ 4MHz
end if
pause 50
readadc C.4, varTEMPBYTE1
if varTEMPBYTE1 >= 100 and varTEMPBYTE1 <= 125 then
pwmout C.2, 249, 499 ; 4000Hz at 50% @ 4MHz
end if
pause 50
readadc C.4, varTEMPBYTE1
if varTEMPBYTE1 >= 0 and varTEMPBYTE1 <= 150 then
pwmout C.2, 199, 399 ; 5000Hz at 50% @ 4MHz
end if
pause 50
readadc C.4, varTEMPBYTE1
if varTEMPBYTE1 >= 0 and varTEMPBYTE1 <= 175 then
pwmout C.2, 166, 333 ; 6000Hz at 50% @ 4MHz
end if
pause 50
readadc C.4, varTEMPBYTE1
if varTEMPBYTE1 >= 0 and varTEMPBYTE1 <= 200 then
pwmout C.2, 142, 285 ; 7000Hz at 50% @ 4MHz
end if
pause 50
readadc C.4, varTEMPBYTE1
if varTEMPBYTE1 >= 0 and varTEMPBYTE1 <= 225 then
pwmout C.2, 124, 249 ; 8000Hz at 50% @ 4MHz
end if
pause 50
readadc C.4, varTEMPBYTE1
if varTEMPBYTE1 >= 0 and varTEMPBYTE1 <= 255 then
pwmout C.2, 110, 221 ; 9000Hz at 50% @ 4MHz

pause 50

end if
goto startreading
 
Last edited:

hippy

Ex-Staff (retired)
The problem with your code is that many of the later IF condition tests are of the form -

if varTEMPBYTE1 >= 0 and varTEMPBYTE1 <= value then

Because the value numbers are increasing, it means the later conditions will be met even when an earlier condition has been applied, this will overwrite any previous PWMOUT operation.

In PICAXE Basic you could express what you want using SELECT-CASE ...

Code:
startreading:
  readadc C.4, varTEMPBYTE1
  Select Case varTEMPBYTE1
    case <= 25  : pwmout pwmdiv16, C.2, 124, 249 ; 500Hz at 50% @ 4MHz
    case <= 50  : pwmout pwmdiv4,  C.2, 249, 499 ; 1000Hz at 50% @ 4MHz
    case <= 75  : pwmout pwmdiv4,  C.2, 124, 249 ; 2000Hz at 50% @ 4MHz
    case <= 100 : pwmout pwmdiv4,  C.2, 82, 165 ; 3000Hz at 50% @ 4MHz
    case <= 125 : pwmout C.2, 249, 499 ; 4000Hz at 50% @ 4MHz
    case <= 150 : pwmout C.2, 199, 399 ; 5000Hz at 50% @ 4MHz
    case <= 175 : pwmout C.2, 166, 333 ; 6000Hz at 50% @ 4MHz
    case <= 200 : pwmout C.2, 142, 285 ; 7000Hz at 50% @ 4MHz
    case <= 225 : pwmout C.2, 124, 249 ; 8000Hz at 50% @ 4MHz
    case <= 255 : pwmout C.2, 110, 221 ; 9000Hz at 50% @ 4MHz
  End Select
  pause 50
  Goto startreading
 

Satchid

Member
Dear Hippy,
This is the best solution for what I am looking for. I can make as many "case <= line ..." as I want, and therefore nearing to an analog to speed solution.
Hippy, Thank you thank you thank you.
Willy
 

fernando_g

Senior Member
This is precisely why I prefer SELECT CASE over IF for complex conditions.
It provides a straightforward, easy to understand procedure.
 

BESQUEUT

Senior Member
Dear Hippy,
This is the best solution for what I am looking for. I can make as many "case <= line ..." as I want, and therefore nearing to an analog to speed solution.
Hippy, Thank you thank you thank you.
Willy
You also can calculate period, so you have a linear variation :
Code:
[color=Blue]do
      readadc C.4[/color][color=Black], varTEMPBYTE1
      [/color][color=Purple]Ana[/color][color=DarkCyan]=[/color][color=Black]varTEMPBYTE1[/color][color=DarkCyan]-[/color][color=Navy]25
      [/color][color=Blue]Select Case [/color][color=Black]varTEMPBYTE1
      [/color][color=Blue]case [/color][color=DarkCyan]<= [/color][color=Navy]25
            [/color][color=Purple]du[/color][color=DarkCyan]=[/color][color=Navy]249[/color][color=Black]: [/color][color=Purple]pe[/color][color=DarkCyan]=[/color][color=Purple]du[/color][color=DarkCyan]/[/color][color=Navy]2
            [/color][color=Blue]pwmout pwmdiv16[/color][color=Black],[/color][color=Blue]c.2[/color][color=Black],[/color][color=Purple]pe[/color][color=Black],[/color][color=Purple]du


      [/color][color=Blue]case [/color][color=DarkCyan]<= [/color][color=Navy]100 
            [/color][color=Purple]du[/color][color=DarkCyan]=[/color][color=Navy]12475[/color][color=DarkCyan]/[/color][color=Purple]Ana [/color][color=Black]: [/color][color=Purple]pe[/color][color=DarkCyan]=[/color][color=Purple]du[/color][color=DarkCyan]/[/color][color=Navy]2
            [/color][color=Blue]pwmout pwmdiv4[/color][color=Black],[/color][color=Blue]c.2[/color][color=Black],[/color][color=Purple]pe[/color][color=Black],[/color][color=Purple]du      
      
      [/color][color=Blue]else
            [/color][color=Purple]du[/color][color=DarkCyan]=[/color][color=Navy]49900[/color][color=DarkCyan]/[/color][color=Purple]Ana [/color][color=Black]: [/color][color=Purple]pe[/color][color=DarkCyan]=[/color][color=Purple]du[/color][color=DarkCyan]/[/color][color=Navy]2
            [/color][color=Blue]pwmout c.2[/color][color=Black],[/color][color=Purple]pe[/color][color=Black],[/color][color=Purple]du  
      [/color][color=Blue]End Select
loop[/color]
 
Top