Interrupt Counter control

Jacobsen

New Member
Can the anyone help my?

I have gotten a readout on the value ”RPMCounter” with the command:

serout 7,T2400,(254,"Speed: ",#RPMCounter," rpm ",255)

Why 2 time "serout!
1: main_loop:goto main_loop
2: interrupt:return

The complete basic code is listed below.

I need to have the ”LKR-motor og interrupt DS1307 Clock” Basic codes for control of the motor
in the first picaxe-28X circuit, as it’s then possible for me to add further phases when needed.
And a second picaxe-28X circuit for parallel display HD44780 with ”hippy” higlighted Basic-codes
for display control.

But how do I transfer the value of the variable ” RPMCounter” to the second circuit since
it’s now supposed to show the RPM counter value?

The speed of the engine is now showing 600 rpm in the display.
I’m using 4Mhz crystal for PICAXE-28X.
Is it possible for me to use 8 or 16Mhz crystal to increase the speed?
I would like a rotating speed of about 2000 rpm.

My Code:

'Declare symbols
symbol RPMCounter = w4 ' b8 and b9
symbol IntMask = b13
'DS1307 SQW/OUT interface on pin 2 of the PICAXE 28X (leg 13)
symbol MASK_BIT = %00000100
'Save locations for interrupt handling
symbol SaveB10 = $50
symbol SaveB11 = $51
'Phase windings on PICAXE output pins
symbol R_Phase = 0
symbol S_Phase = 1
symbol T_Phase = 2

'#########################################################
' Start of code
'#########################################################
'Set up the DS1307 on the 12c bus
i2cslave %11010000, i2cslow, i2cbyte
pause 40
'Set 1307 to 00:00:00, Wednesday, 30 November, 05 and SQW/OUT to 1Hz
writei2c 0, ($00, $00, $00, $04, $30, $11, $05, $10)
'Do something (what?) to the LCD
serout 7,T2400,(254,1,255)
pause 30
serout 7,T2400,(254,128)
'Set the R phase high - first run only
high R_Phase
'Toggle the mask bit as we want the -ve edge of SQWE...
IntMask = IntMask ^ MASK_BIT
'...and inititialise the interrupt
setint IntMask, MASK_BIT

'#########################################################
' Main loop
' This loop runs continuously
' Every 1 second, caused by the 1307 interrupt, the RPM is
' displayed on the LCD
'#########################################################
main_loop:

serout 7,T2400,(254,"Speed: ",#RPMCounter," rpm ",255)

'Delay according to speed controller value
gosub speed_delay
'Rotate motor...
high R_Phase
high S_Phase
low T_Phase
'Delay according to speed controller value
gosub speed_delay
'Rotate motor...
low R_Phase
high S_Phase
high T_Phase
'Delay according to speed controller value
gosub speed_delay
'Rotate motor...
high R_Phase
low S_Phase
high T_Phase
'Increment the RPM counter
RPMCounter = RPMCounter + 1
goto main_loop
'#########################################################
' speed_delay
' Destroys b10, b11
'#########################################################
speed_delay:
'Initialise a temporary variable
b10 = 0
readadc 0,b11 'read A0
delay_loop:
b10 = b10 + 1
if b10 >= b11 then end_speed_delay
goto delay_loop
end_speed_delay:
return

'#########################################################
' Interrupt
'#########################################################
interrupt:
'save working variables in case of use in the interrupt routine
poke SaveB10, b10
poke SaveB11, b11
if IntMask = MASK_BIT then re_enable_interrupt
'This is the code that runs every 1 second...
'Show the RPM counter on the LCD display...
'...but convert to RPM first...
RPMCounter = RPMCounter * 60

sertxd("Value: ",#RPMCounter,13,10)

serout 7,T2400,(254,128,"Speed: ",#RPMCounter," rpm ")

'...and then reset the counter for use in the next second
RPMCounter = 0
re_enable_interrupt:
'Toggle the mask bit...
IntMask = IntMask ^ MASK_BIT
'...and reset the interrupt
setint IntMask, MASK_BIT
'restore all saved variables
peek SaveB10, b10
peek SaveB11, b11
return

Best regards
Monie
 

MartinM57

Moderator
<<The speed of the engine is now showing 600 rpm in the display.>>

But what is the speed of the motor? Are you sure it's actually 600rpm? Your algorithm assumes that the 3 sets of phase outputs rotates the motor one revolution. Is that true?

<<I’m using 4Mhz crystal for PICAXE-28X. Is it possible for me to use 8 or 16Mhz crystal to increase the speed?>>

What do you think? The main loop will run faster by about a factor of 2 or 4, depending on the overclocking you do. Will that make the motor run faster? Maybe it will, maybe it won't. If the phase pulses are too short, I expect the motor won't rotate at all, so there has to be some limit. You'll have to do some experiments!

<<I would like a rotating speed of about 2000 rpm.>>

Try overclocking and doing some experiments!

<<And a second picaxe-28X circuit for parallel display HD44780 with ”hippy” higlighted Basic-codes for display control.

But how do I transfer the value of the variable ” RPMCounter” to the second circuit since it’s now supposed to show the RPM counter value?>>

Well you never mentioned that slight change to the design before! Suggets you search the forum for inter-PICAXE communications. It's been covered extensively. It's not trivial!

Bear in mind that interrupt processing, sending characters to the LCD, sending data to another picaxe etc all take processing time and stop your main loop from running while they are being performed - remember the picaxe can't to two things at exactly the same time - so you may not get max speed from the motor or it may not run smoothly.

Edited by - MartinM57 on 12/12/2005 7:13:53 PM
 

evanh

Senior Member
Damn! That's gotta be noisy, three steps for a whole rev!

Ok, to get some more speed one could:
- Remove the serout from the main loop.
- Shorten the highs and lows to a single command for each motor step, ie: pins=%0000101 ' TsR
- Change the readadc to only once per rev.
- Replace the delay loop with a pause, ie: pause b11

Your gosub now contains only a single command so should be inlined. That leaves just nine lines in the main loop and no gosubs. :)


Evan
 

Jacobsen

New Member
I will try overclocking and doing some experiments!

I just don't understand why "serout 7,T2400,(254,128,"Speed: ",#RPMCounter," rpm ")" needs to appear twice in the basic codes to make them show in the display.

I would be very happy if you could help me with that.

A very merry Chritstmas from Denmark

Bedst regards
Monie
 

evanh

Senior Member
Well, the line are not the same. Compare:

serout 7,T2400,(254,"Speed: ",#RPMCounter," rpm ",255)
serout 7,T2400,(254,128,"Speed: ",#RPMCounter," rpm ")

What does 255,254, and 128 do to the display?


Evan
 

Jacobsen

New Member
To MartinM57 and evanh

Below are my codes, which are now working!

At start up 600rpm are shown in the display, but after modifications
to the code, it now shows 7860rpm.

In the beginning of the code, I've changed:

Serout 7,T2400,(254,1,255)
Pause 30
Serout 7,T2400,(254,128)

In the main_loop: goto main_loop there is no longer an output to the
display. The output is solely from the interrupt part, as it was
intended in the beginning.

I don't know how much time is spent sending the variable
"RPMCounter"'s value to the second Pic-circuit?

Do you have any suggestions for a such basic code, so I have some sort
of starting point for further experiments?

I would like to be able to see the revolutions count in the parallel display

My code:

'Declare symbols
symbol RPMCounter = w4 ' b8 and b9
symbol IntMask = b13
'DS1307 SQW/OUT interface on pin 2 of the PICAXE 28X (leg 13)
symbol MASK_BIT = %00000100
'Save locations for interrupt handling
symbol SaveB10 = $50
symbol SaveB11 = $51
'Phase windings on PICAXE output pins
symbol R_Phase = 0
symbol S_Phase = 1
symbol T_Phase = 2

'#########################################################
' Start of code
'#########################################################
'Set up the DS1307 on the 12c bus
i2cslave %11010000, i2cslow, i2cbyte
pause 40
'Set 1307 to 00:00:00, Wednesday, 30 November, 05 and SQW/OUT to 1Hz
writei2c 0, ($00, $00, $00, $04, $30, $11, $05, $10)
'Do something (what?) to the LCD
serout 7,T2400,(254,1,255)
pause 30
serout 7,T2400,(254,128)
'Set the R phase high - first run only
high R_Phase
'Toggle the mask bit as we want the -ve edge of SQWE...
IntMask = IntMask ^ MASK_BIT
'...and inititialise the interrupt
setint IntMask, MASK_BIT

'#########################################################
' Main loop
' This loop runs continuously
' Every 1 second, caused by the 1307 interrupt, the RPM is
' displayed on the LCD
'#########################################################
main_loop:

'Delay according to speed controller value
gosub speed_delay
'Rotate motor...
high R_Phase
high S_Phase
low T_Phase
'Delay according to speed controller value
'Rotate motor...
low R_Phase
high S_Phase
high T_Phase
'Delay according to speed controller value
'Rotate motor...
high R_Phase
low S_Phase
high T_Phase
'Increment the RPM counter
RPMCounter = RPMCounter + 1
goto main_loop
'#########################################################
' speed_delay
' Destroys b10, b11
'#########################################################
speed_delay:
'Initialise a temporary variable
b10 = 0
readadc 0,b11 'read A0
delay_loop:
b10 = b10 + 1
if b10 >= b11 then end_speed_delay
goto delay_loop
end_speed_delay:
return

'#########################################################
' Interrupt
'#########################################################
interrupt:
'save working variables in case of use in the interrupt routine
poke SaveB10, b10
poke SaveB11, b11
if IntMask = MASK_BIT then re_enable_interrupt
'This is the code that runs every 1 second...
'Show the RPM counter on the LCD display...
'...but convert to RPM first...
RPMCounter = RPMCounter * 60
serout 7,T2400,(254,128,"Speed: ",#RPMCounter," rpm ")
'...and then reset the counter for use in the next second
RPMCounter = 0
re_enable_interrupt:
'Toggle the mask bit...
IntMask = IntMask ^ MASK_BIT
'...and reset the interrupt
setint IntMask, MASK_BIT
'restore all saved variables
peek SaveB10, b10
peek SaveB11, b11
return


A very merry Chritstmas from Denmark

Bedst regards
Monie
 

MartinM57

Moderator
<<At start up 600rpm are shown in the display, but after modifications to the code, it now shows 7860rpm.>>

With overclocking or not?

Back to the point I made earlier - are you sure that this is indicating the speed of the motor (which I don't believe) or the speed at which the software is going around the main loop (which I do believe). For example, if you overclocked to 4x speed you'd see over 30000 rpm - but will your motor really be doing that speed?

If the two are not the same, then I think you need to sort that out first, before working out how to get that info to the other PICAXE...
 

Jacobsen

New Member
To MartinM57


shows 7860 rpm in the display
No overclocking uses (4Mhz crystal)

It's indicating the speed at which the software is going around the main loop.

<<If the two are not the same, then I think you need to sort that out first, before working out how to get that info to the other PICAXE... >>

It's the same Type 2 x PICAXE-28X with 4Mhz crystal

in the first picaxe-28X circuit, as it’s motor speed code.
And a second picaxe-28X circuit for parallel display HD44780 with ”hippy” higlighted Basic-codes for display.

A very merry Chritstmas from Denmark

Bedst regards
Monie
 

MartinM57

Moderator
<<If the two are not the same, then I think you need to sort that out first, before working out how to get that info to the other PICAXE... >>

No, I mean if the speed of going round the loop is different to the speed of the motor then I can't really see the point in sending the data to another PICAXE. The famous saying is "Rubbish in, rubbish out" Why display an RPM which is (almost) completely guaranteed to be incorrect?
 

evanh

Senior Member
Sounds to me like it's not connected to a motor yet. So the statement of the RPM being just the software looping rate is valid.


Evan
 

evanh

Senior Member
>> I don't know how much time is spent sending the variable "RPMCounter"'s value to the second Pic-circuit?

Two points: The serout command is CPU hungry because it is bit-bashed where as sertxd is a real commport so will be less of a burden. Secondly, when the transmit buffer fills up the software must wait for more room in the buffer before continuing so it's a good idea not to send to much data to the display.

Evan
 

evanh

Senior Member
>> I would like to be able to see the revolutions count in the parallel display

I assume this is the serout you are talking about but I don't understand what the problem is. You have already said the RPM is being displayed.


Evan
 

hippy

Technical Support
Staff member
<i>sertxd is a real commport </i>

I think you'll find SERTXD is bit-banged just like SEROUT; the Serial In and Serial Out pins don't go the pins the on-chip USART is connected to, and the USART can't connect to a PC without an inverter.
 

Jacobsen

New Member
TO All

As work takes up way too much of my time, I haven't posted before now.

Please look at this: www.sunwind.dk/2xpicaxe-28x.pdf

I want to send the variable :&quot;#RPMCounter&quot; from first picaxe-28x (link7)
to second picaxe-28x (link 6)

Should this Command:&quot;SERTXD (#RPMCounter)&quot; be in the first circuit?
And should &quot;SERRXD (#RPMCounter)&quot; be in the second Pic-circuit?

Or how could the codes look?

I realise that some time is being used on the data transfers, but
can't this extra time be deducted in some way?

I need to make a PCB, hence these questions on how to connect the circuits.

How Write link: www.sunwind.dk/2xpicaxe-28x.pdf with Cmd:
&quot;Extenal Web Link&quot; ??


A very merry Chritstmas from Denmark

Vy 73 de OZ2ZT

Best regards
Monie
 

evanh

Senior Member
The method for linking is listed in the protocol button <A href='http://www.rev-ed.co.uk/picaxe/policy.htm' Target=_Blank>External Web Link</a> at the top of the forum pages.

You will notice there is no SERRXD equivalent to the SERTXD command. You can't use the serial input pin (pin 6 on the 28X) for anything other than downloads. Any time the Picaxe sees a high state on this pin it stops running the BASIC program and goes into download mode waiting for the editor to give it a new program.

A basic connection between two Picaxes would be to directly wire a SEROUT pin or the SERTXD pin on one chip to a SERIN pin on the other chip and the same back the other way if you want bidirectional comms.


Evan
 

evanh

Senior Member
The way to reduce CPU usage from serial transmission is to not send so much data. This can be done in two parts: Send less data in each packet and send less packets.

The one second interrupt that you are using already reduces the frequency of packets so that is done. :)

To reduce the packet size you should just send the active values and not the whole string. Let the receiving Picaxe manage the way the readings are to be displayed.


Evan

Edited by - evanh on 12/17/2005 12:29:34 AM
 

Jacobsen

New Member
<b> Hello evanh </b>

Thank you very much for the info on how to insert the &quot;Web-link&quot;

I understand that transferring the value of the &quot;RPMCounter&quot; variable
will take up too much time.
As soon as I have some results from the motor speed experiments I'll
let you know.

Please see the control part here: <A href='http:// www.sunwind.dk/solar-pumpe.jpg ' Target=_Blank>External Web Link</a>

But to the experiments!
How can I for instance transfer a variable named &quot;TestInOut&quot;
containing the number &quot;&quot;99&quot; to the second picaxe-28X?
Shall I transfer it in the same way as we send data to the LCD-display
via e.g. Cmd:
&quot;serout 7,T2400,(254,128,TestInOut)&quot; or should Cmd: SERTXD, SERIN og
SEROUT be used here?
I know that to be able to upload the Basic-codes til PICAXE-28X pin 6
og 7 are to be used, but I'm not quite sure how this can be done.

It would be great if you could supply me with a small code example, so
I could run some tests and learn from the process.

A very merry Christmas from Denmark


<b> Best regards
Monie </b>


Edited by - Monie on 12/17/2005 8:33:55 PM
 

evanh

Senior Member
The Picaxe has a major flaw with many commands, and that is that it performs no background processing. With a couple of exceptions where there wasn't much choice, namely SERVO.

Right, now I got that off my chest, the SERIN command on the &quot;display&quot; Picaxe will need to be ready to receive the data each time it is sent from the &quot;stepping&quot; Picaxe. You have an advantage in that the display Picaxe can know beforehand when the stepping Picaxe is about to send it's data and that is because of the 1 second interrupt pulse. You could wire it to both Picaxe chips and have an interrupt routine in both Picaxes run at the same time.

That's just an idea of one way to skin this one ...


Evan
 

evanh

Senior Member
If you want generic example comms then you can do a search, both on this forum and elsewhere.

http://www.rev-ed.co.uk/picaxe/links.htm

Btw: The reason why I haven't given example code is because I don't know what you have at the moment nor do I know what you are wanting (I've been guessing quite a lot) and, obviously, I've not tried to think about what would be best choices.


Evan
 

Jacobsen

New Member
To all

I will try to do some experiments!

An thanks to all some has help me.


A very merry Chritstmas from Denmark


Thanks, all.
Bedst regards
Monie
 
Top