Pwmout problem

jikmar

New Member
Hello,

I am fairly new to picaxe: this is my first project, which has been going well until I started using pwmout to control a motor.

It is a program to test a thermostatic control system, which needs to adjust a temperature by means of a pwm controlled dc motor.

I have had a series of headaches involving not being able to start, stop, or restart the motor after stopping.

Unfortunately the code almost completely fills the 40X1 chip that i am using, hence posting it is tricky. So I have cut and pasted a few bits of it into a smaller version, which now works perfectly. However I am struggling to see what in my larger version can prevent it from working.

Question: could someone please have a look at the code below, and tell me if there are any known issues that might prevent this from working if certain other commands are used in between the motor start/stop commands?

The rest of my program uses an interrupt triggered by timer overflow to measure temperatures (with pulsin) and pressures (with readadc10). It also uses the i2c bus to read from the ds1307 clock and drive an LCD.

Note that the code following works, I am just inquiring if there are known issues with doing this sort of stuff, which makes my other code fail...

Code:
symbol mwt=b9			'mwt in tenths of degrees C above 30°
symbol settmp= 110                         'equivalent to 41 degC
setfreq m8			'set the clock speed to 8MHz
mwt = 0


main:

gosub setpwm

sertxd ("motor started",13,10)

for b0 = 0 to 20	;delay
pause 250
next b0
	
	pwmout 1,253,0			;stop the motor
	pwmout 1 off	

sertxd ("motor stopped",13,10)

for b0 = 0 to 20	;delay
pause 250
next b0

gosub setpwm

sertxd ("motor started",13,10)
	
for b0 = 0 to 20	;delay
pause 250
next b0
			
	pwmout 1,253,0			;stop the motor
	pwmout 1 off
	
sertxd ("motor stopped",13,10)
	
let mwt=mwt+83

goto main

'****************************************


setpwm:
	
high portc 1		;make sure this is configured as an output
low portc 1
	
	if mwt<settmp then 
		goto warmup
		endif	
;cooldown:
	low portc 7
	let b3 = mwt-settmp
	goto adjusttemp	
	
warmup:	
	
	high portc 7	;energise the pin to reverse the motor
	let b3 = settmp-mwt
	
	
adjusttemp:
	for b2 = 8 to 1 step -1
		let w2 = b2*127
		sertxd ("w2=",#w2,13,10)
		if b3>91 then exit		
		let b3 = b3+13				
	next b2
	
	pwmout 1,253,w2		'91 = 13*(8-1)	
	
return			;return from setpwm...
...Someone is going to tell me to comment out the rest of the program piece by piece until it works. I will try to do this now, but I also tried this with a previous version of the code and it yielded nothing sensible. I fear there is something weirder than usual going on here, so hence the cry for help!

Thanks in anticipation...


Picaxe 40X1
Prog Editor 5.2.0
 

hippy

Ex-Staff (retired)
Along the same lines as removing code out is to create test programs which test one part of the functionality at a time. So let's start with motor control as that's what is ultimately the end goal. Some of the things you may have done already and do form part of the code you posted ...

Write a program which simply turns the motor on and off and get that working. Alter it so you can cause the motor to run a speed which is specified and you can change the speed, start, stop and re-start the motor as you need to.

If you want to have smooth transitioning from one speed to another, then add that to the motor control routines, adjust the tests and check it works again.

Now you can shift your focus to reading the temperature sensor and determining what speed you need to set your motor. Once that's working you can integrate the two; simply call the SetPwm routine whenever you need to change its speed or start or stop the motor.

What seems to me to be the problem with the code you have is the design. You seem to have temperature control included as part of the speed control function and I cannot easily visualise how the two work together.

This is what would be called a "break-down in modularisation". I always try and visualise a system in terms of 'stupid people' role-playing the system then it's easier to understand the interactions going on. I call them 'stupid' because they only do what they are told and have no ability to know anything they aren't told.

In this case one person has a thermometer and tells the other how fast they should be waving their arms around to cool the room. The other, completely unaware of anything at all about temperature, simply waves their arms around at the speed instructed.

To stop torn ligaments when changing speed of arm waving, waving rate is best increased or decreased slowly this would be a function built into the arm waver and the thermometer reader wouldn't need to be aware of it. A speed is asked for and the arm waver will at some point get to that speed.

Likewise the thermometer reader can look at the temperature and decide if the waving should be faster or slower than was asked for and can do their own ramping up and down of requested speed.

The real key is in splitting the system so there is only minimal interaction and without an actor having to know infrmation which the other actor knows, ie the arm waver shouldn't need to know about termperatures, simply how fast to wave their arms.

I think it might be a good idea to sit down and re-think or at least clairify how your current modularisation works.
 

jikmar

New Member
Thanks Hippy,

This seems good advice and is indeed what I am trying to do by making the program I posted. I guess what you are saying about arm-waving and breakdown of modularisation comes partly from the let "mwt=mwt+83" (attempt at pseudo-randomisation) part of it which was just put in to make sure that the motor gets a chance to run at different speeds, stop and also transition from one speed to another. It does this ok. I am sorry for confusing you and didn't explain this.

What I have discovered since I made the last post are 2 significant things.

the first was a stupid mistake in the program flow :rolleyes:

the second is that I have an electromagnetic interference problem from the motor. This manifests itself firstly as erroneous readings from the temp probes, but more recently, a complete freezing of the picaxe. I have now tested this by replacing the motor with a pair of LEDs (red for forward, green for reverse) which require much lower current than the motor and this stops the picaxe freezing. I have noticed also that stripping the motor wire out of the box altogether improves the stability of the temp readings. The EMI also seems to interfere with the DS1307 clock chip and make it run fast.

I now have to go and redesign the hardware to put the power transistor (not a particularly high-power transistor, though) further from the picaxe and shield it.

I shall let you know how it goes after that. I think there may still be a problem with the pwmout stopping for no obvious reason.

Incidentally, I had a previous version of this code in which the pwmout ran though multiple nap commands exactly as the manual is at pains to point out that it won't. I cured this by issuing

Code:
pwmout 1,253,0
pwmout 1 off
Without the second line it never stops - I didn't know this and it isn't clear from the manual that you have to do BOTH.

Now I seem to have a situation where it stops prematurely. I will sort the EMI problem and go from there.

thanks again for your time,

Mike.
 
Top