What have I got myself into.

Zef

Member
Hi, new user to the forum. Warning this will be a lengthy posts. Sorry in advance.
Well a little background might help. I'm a classic car restorer. One of my customers has a road legal Dalek based off a Mini. He brought it in for a resto-mod and wanted FX installing. Like an idiot I said "No problem" and hence I'm here. Some of what I've managed to do myself is quite nice, 40 random flashing led's, in 8 groups of 5, on the dashboard using 1 18M2. I've got the SPE035 working playing random music. I've written the code to articulate the Dalek gun, Eye stalk and Eye Iris. I've even managed to, although not tested fully, get the picaxe controlling the servo's to talk to the picaxe controlling the Gun light and Eye light. What I would like is the gun light to flash and as it does so send a signal to the SPE035 to play the gun noise. I understand this should be possible if I put the gun noise file as an advert but this bit is way over my head. I'll try list below the systems I have and how they are broken down to make my life easier (or so I think). I would appreciate any feedback/help you could give me.

all code at bottom.

Servo Picaxe 18M2 controlling Dalek gun (2 servo's) and Dalek eye (2 servo's) independently.
Light control Picaxe 18M2 controlling Dalek eye light and Dalek gun light independently.
Music Picaxe SPE035 playing Dr Who music and other tracks randomly.
Head Picaxe (yet to work on, to control a motor to swing the head about)
Smoke Picaxe 18M2 to control a smoke machine and produce smoke effect under the Dalek at random times and lengths.
Dash light Picaxe 18M2 to flash 40 lights as described above.

Servo Picaxe takes a digital input (a switch) on 2 inputs to turn on either the eye movement or the gun (or both). This then outputs to the Light control Picaxe to turn on the Eye light and the Gun light (Gun effect to light up as it would fire). Brief explanation why those are separate, Servo's are 5v and the lights are 12v. Thinking as I'm typing it might be better voltage wise to get the servo control picaxe to talk to SPE035 AND the Light control picaxe to play the noise and flash the lights as obviously for ease the Light control is running with the 12V modification. I've yet to write the Light Control Picaxe code as it should be straightforward....wait for input and then turn on a light.

God I hope that lot made sense to someone.
Code is below for you to laugh at and tell me to rewrite the lot "you bloody idiot" :ROFLMAO::ROFLMAO:

Code:
' For Picaxe M18M2
' Servo picaxe
' 1 start operation to control the other
' 4 start operations so they run simultaneously

' Initial servo values are generic until limits are known and can be thus set.

Symbol eyeinput = pinC.0
Symbol guninput = pinC.1
Symbol iris = w1
Symbol eyeV = w3
Symbol gunH = w5
Symbol gunV = w7
Symbol wait1 = w9
Symbol wait2 = w11
Symbol wait3 = w13

start0:
if eyeinput = 1 then start1 ' Take input from Eye control switch and run Start 1
if eyeinput = 1 then start2 ' Take input from Eye Control switch and run start 2
if guninput = 1 then start3 ' Take input from Gun control switch and run Start 3
if guninput = 1 then start4 ' Take input from Gun control switch and run Start 4

' Send signal to light control Picaxe to turn on Eye light
if eyeinput = 1 then
high B.7
else if eyeinput = 0 then
low B.7
end if

goto start0

start1:
' Iris Servo, activate the iris servo to open and close the iris at random

    Do
        random w0
        b18 = w0/142//3000+1
        loop until b18<>b19
        b19=b18
        ' generate a reasonable quality random number
       
random w8
iris = b19
iris = b19//195+10 ' random servo setting
wait1 = w8
wait1 = w8//3000+500 ' random delay between movements
servo 1,iris ' move iris servo
pause wait1 ' delay before next move
goto start0

start2:
' Eye Vertical, activate
    Do
        random w2
        b20 = w2/102//3000+1
        loop until b20<>b21
        b21=b20
        ' generate a reasonable random number
   
    random w10
    eyeV = b21
    eyeV = b21//195+10 ' random servo setting
    wait2 = w10
    wait2 = w10//3000+500 ' random delay between movements
    servo 2,eyeV ' move eye stalk up/down
    pause wait2 ' delay between movements
goto start0

start3:
' Gun Horizontal, move the gun horizontally
    random w4
    random w12
    gunH = w4
    gunH = w4//195+10 ' random servo setting
    wait3 = w12
    wait3 = w12//3000+500 'random delay between movements
    servo 3,gunH ' move servo
    pause wait3 ' delay between movements
goto start0

start4:
' Gun Vertical, move the gun vertically
    random w6
    gunV = w6
    gunV = w6//195+10 ' random servo setting
    servo 4,gunV ' move servo
    pause wait1 ' delay between movements
goto start0
SPE035 music picaxe
Code:
'BASIC converted from file:
'C:\ProgramData\Revolution Education\PICAXE Editor\Samples\Blockly\AXE171 - PICAXE 14 Audio Kit\14M2\AXE171 - Play Sequential.xml
'Converted  2020-11-15 at 20:55:27

' Code modified from the sample file as I have no clue about what is needed by
' way of programming and what can be discarded.

symbol varA = w0

main1:
    high B.4
    pause 1
    setfreq m8
    serout B.4, T9600_8, ($7E, $FF, $06, $09, $00, $00, $02, $EF)    ;SPE035 initialise
    setfreq mdefault
    pause 100
    pause 4000
    setfreq m8
    serout B.4, T9600_8, ($7E, $FF, $06, $06, $00, $00, 20, $EF)    ;SPE035 volume
    setfreq mdefault
    pause 100
    pause 1000
    do
      random w1
    let VarA = w1
    VarA = w0//13+1 ' select a random track and play.
      setfreq m8
      serout B.4, T9600_8, ($7E, $FF, $06, $12, $00, $00, varA, $EF)    ;SPE035 play
      setfreq mdefault
      pause 100
      pause 500
      do
          pause 10
      loop until pinC.2 = 1
    loop
    stop
Thanks for your patience.

*edited to include my further terrible code*

Smoke machine

Code:
' For Picaxe 18M2
' Smoke machine
' random fire smoke effect switching a 12v DC to 240v AC relay on B.0

Symbol dosmoke = w6
Symbol delay = w11

' following code waits for an input on C.0 which corresponds to
' the smoke machine getting up to temperature, switching done via
' a relay to protect picaxe from 240v AC
main:
    if pinC.0 = 1 then
      do
          pause 10
      loop until pinC.0 = 0
    else
      call Smoke
    endif


' Following code should randomly fire smoke for a random length of time
' between a random length delay
' I am trying to set the delay to be up to a minute ( smaller length of
' time during testing will be set )
Smoke:
      do
            ' 3 do loops to create a large enough quality random number
        do
            random w0
            b5 = w0/198//4000+1
        loop until b5<>b6
        b6 = b5
           
        do
            random w1
            b7 = w1/350//4000+1
        loop until b7<>b8
        b8 = b7
       
        do
            random w2
            b9 = w2/42//4000+1
        loop until b9<>b10
        b10 = b9
       
        w5 = b6+b8+b10 ' add the 3 random numbers
        w6 = w5*10        ' multiply the result by 10
       
        ' This is a lengthy procedure but during testing using
        ' a simpler random number generation did not give a
        ' random result!?!
       
        random w10
        w11 = w10//20000+5000 ' set the length of delay between firings
        pause delay
        high B.0        ' fire smoke
        pause dosmoke    ' for this length of time
        low B.0        ' turn off smoke
   
    ' the following checks that the smoke machine is still at temperature
    ' and either returns to main to wait until it is, or loops through
    ' producing smoke.
    if pinC.0 = 1 then
            Goto main
            else
    end if
      loop
    return
 
Last edited:

inglewoodpete

Senior Member
First, welcome to the PICAXE Forum.

Next, have a read of the "Read me first" sticky at the top of the main forum list. In particular, the use of code tags, which helps keep your code structure indentations in place, improving its readability for people unfamiliar with it. Finally, including comments in the code tells other forum members what you are intending your code to do. Without comments we can only guess what is intended. Comments will also help you if you should return to the code in a few month's or year's time.

You can edit your post to add both code tags and comments.

Without useful comments, I have not tried to delve into your code. Some errors are obvious, some are just questionable code.

EG:
  • Why did you include all of those SetFreq commands?
  • I don't know why you have Start2 and Start4 code, since these routine are triggered by the same conditions as Start1 and Start3.
  • Your stop statements are not required - any they are unreachable anyway. I have never used a stop statement in about 15 years of programming many hundred PICAXEs
  • You code starting at main1 appears to be unreachable.
  • Sequential pause commands?
 

Buzby

Senior Member
Hi Zef,

Welcome to the forum !.

Looking at your code, it looks like your 'Music' board is just playing random selections one after the other.

Your requirement "What I would like is the gun light to flash and as it does so send a signal to the SPE035 to play the gun noise." could be done using an interupt, but a simpler method is to reverse the direction of the command.

Instead of the gun telling the music to make a noise, let the music tell the gun when to flash.

This could be done with a simple digital pin which is 'set' when the music is a gun noise and 'cleared' if the music is not a gun noise.

Can you post a picture ?. I've never seen a road legal Dalek !.

Cheers,

Buzby
 

Zef

Member
First, welcome to the PICAXE Forum.

Next, have a read of the "Read me first" sticky at the top of the main forum list. In particular, the use of code tags, which helps keep your code structure indentations in place, improving its readability for people unfamiliar with it. Finally, including comments in the code tells other forum members what you are intending your code to do. Without comments we can only guess what is intended. Comments will also help you if you should return to the code in a few month's or year's time.

You can edit your post to add both code tags and comments.

Without useful comments, I have not tried to delve into your code.
Thanks for your reply. I have edited the code including comments, it might make more sense to you now as to what I was trying to achieve.

The music picaxe code is basically the sample included in the editor suite modified to play the 13 files I have. Apart from that I've no real clue as to why it's set. It was in the sample so I assumed it was needed.

The stop statements I added as I though they were needed, they are gone now. I assumed I needed them as I am multi tasking the programs.
The music program does work as intended, plays random tracks and waits until the track ends before starting the next.

I hope my commenting the code clarifies what I'm thinking and reasons for doing it the way I have?
 

Zef

Member
Hi Zef,

Welcome to the forum !.

Looking at your code, it looks like your 'Music' board is just playing random selections one after the other.

Your requirement "What I would like is the gun light to flash and as it does so send a signal to the SPE035 to play the gun noise." could be done using an interupt, but a simpler method is to reverse the direction of the command.

Instead of the gun telling the music to make a noise, let the music tell the gun when to flash.

This could be done with a simple digital pin which is 'set' when the music is a gun noise and 'cleared' if the music is not a gun noise.

Can you post a picture ?. I've never seen a road legal Dalek !.

Cheers,

Buzby
What I good idea. I hadn't thought of doing things that way round. There are 2 tracks I would like to be the main playing ones. I can remove the others easily and just let them play sequentially. The gun noise I would still like as a random and playing over the main 2 tracks. If I'm right I could use the gun noise as an "advert" and that would work? Probably wrong but hey ho :D

I'll upload a photo later when I've shrunk it's size. In the meantime it is the vehicle as seen on BBC's Blue Peter
 

Buzby

Senior Member
... The gun noise I would still like as a random and playing over the main 2 tracks. ...
The music plays some randomly selected tracks, say 1,2,3,4,5,6.

Tracks 1 to 5 are music, and 6 is the gun sound.

So some code structured like this will play all tracks randomly, but also trigger the flash only when track 6 is started .....
Code:
do

   { 
   ... Make random number for TrackNum,1-6
   }

   if TrackNum = 6 then        ' Set gun trigger if track is gun sound
           HIGH GunTrigger
   else                                    ' Clear gun trigger if track is not gun sound
           LOW GunTrigger
   endif

   serout B.4, T9600_8, ($7E, $FF, $06, $12, $00, $00, TrackNum, $EF)    ;SPE035 play

loop
The code above is just a skeleton. You will obviously need to use an output pin for GunTrigger.

It's amazing to see that Dalek is still going, that video is from 1987 !.

Cheers,

Buzby
 

Zef

Member
The music plays some randomly selected tracks, say 1,2,3,4,5,6.

Tracks 1 to 5 are music, and 6 is the gun sound.

So some code structured like this will play all tracks randomly, but also trigger the flash only when track 6 is started .....
Code:
do

   {
   ... Make random number for TrackNum,1-6
   }

   if TrackNum = 6 then        ' Set gun trigger if track is gun sound
           HIGH GunTrigger
   else                                    ' Clear gun trigger if track is not gun sound
           LOW GunTrigger
   endif

   serout B.4, T9600_8, ($7E, $FF, $06, $12, $00, $00, TrackNum, $EF)    ;SPE035 play

loop
The code above is just a skeleton. You will obviously need to use an output pin for GunTrigger.

It's amazing to see that Dalek is still going, that video is from 1987 !.

Cheers,

Buzby
Thanks Buzby

looks like the code works in simulation. I'll have to download it to the Picaxe later, It's at the workshop and I ain't.
This is what I've modified the code to. Reducing the number of tracks to 3 (for now at least)

Code:
'BASIC converted from file:
'C:\ProgramData\Revolution Education\PICAXE Editor\Samples\Blockly\AXE171 - PICAXE 14 Audio Kit\14M2\AXE171 - Play Sequential.xml
'Converted  2020-11-15 at 20:55:27

' Code modified from the sample file as I have no clue about what is needed by 
' way of programming and what can be discarded.

symbol TrackNum = w0
Symbol GunTrigger = C.0

main1:
    high B.4
    pause 1
    setfreq m8
    serout B.4, T9600_8, ($7E, $FF, $06, $09, $00, $00, $02, $EF)    ;SPE035 initialise
    setfreq mdefault
    pause 100
    pause 4000
    setfreq m8
    serout B.4, T9600_8, ($7E, $FF, $06, $06, $00, $00, 20, $EF)    ;SPE035 volume
    setfreq mdefault
    pause 100
    pause 1000
    do
      random w1
    let TrackNum = w1
    TrackNum = w0//3+1 ' select a random track and play.
    
     if TrackNum = 3 then        ' Set gun trigger if track is gun sound
           HIGH GunTrigger
   else                                    ' Clear gun trigger if track is not gun sound
           LOW GunTrigger
   endif

   serout B.4, T9600_8, ($7E, $FF, $06, $12, $00, $00, TrackNum, $EF)    ;SPE035 play

'loop
    
 '     setfreq m8
 '     serout B.4, T9600_8, ($7E, $FF, $06, $12, $00, $00, varA, $EF)    ;SPE035 play
 '     setfreq mdefault
      pause 100
      pause 500
      do
          pause 10
      loop until pinC.2 = 1
    loop
    stop
 

Zef

Member
Nice Dalek.
I want one, complete with the driver.
Good luck with your projects.
Bear..
Thanks Bear.
I'm sure she's looking a little older (aren't we all). I've talked to the guy who originally made the thing and he was surprised it was still going.
I'll be glad to see the back of it. I'd say "Never again" but someone will rock up with something unusual that no one else will touch and I'll say yes AGAIN, I guess I never learn. :ROFLMAO: :ROFLMAO:
 

Zef

Member
So I've written the Light Picaxe code.
Works in simulation, it's going to be a busy week next week wiring these all in and fingers crossed it all works and nothing goes up in flames.....I've already smoked 1 servo, don't ask 🤦‍♂️
Code as follows.
Code:
' For 18M2

' Light Picaxe
' Take 2 inputs and output to 2 LED's independently

' Set Inputs
Symbol EyeInput = pinc.0
Symbol GunInput = pinc.2
' Set Outputs
Symbol EyeLight = B.0
Symbol GunLight = B.2

Start0:

Do
    If EyeInput = 1 then ' Get Eyeinput
        High EyeLight  ' Turn EyeLight on
    else
        Low Eyelight   ' Clear Eyelight if EyeInput is off
    endif
loop

Start1:

Do
    If GunInput = 1 then ' Get GunInput
        High GunLight  ' Turn GunLight on
    else
        Low Gunlight   ' Clear GunLight if GunInput is off
    endif
loop
 

Buzby

Senior Member
Hi Zef,

You don't need more than one task to perform the actions you require.

Just a single 'do ... loop' will work fine ....
Code:
Do
    If EyeInput = 1 then ' Get Eyeinput
        High EyeLight  ' Turn EyeLight on
    else
        Low Eyelight   ' Clear Eyelight if EyeInput is off
    endif

    If GunInput = 1 then ' Get GunInput
        High GunLight  ' Turn GunLight on
    else
        Low Gunlight   ' Clear GunLight if GunInput is off
    endif

loop
 

Zef

Member
Hi Zef,

You don't need more than one task to perform the actions you require.

Just a single 'do ... loop' will work fine ....
Code:
Do
    If EyeInput = 1 then ' Get Eyeinput
        High EyeLight  ' Turn EyeLight on
    else
        Low Eyelight   ' Clear Eyelight if EyeInput is off
    endif

    If GunInput = 1 then ' Get GunInput
        High GunLight  ' Turn GunLight on
    else
        Low Gunlight   ' Clear GunLight if GunInput is off
    endif

loop
I think I'm stuck in my multi-tasking mindset. Thanks for the improved code. I should have realised running a code that small would be quick enough as to appear instantaneous. Are there any improvements that could be made in my other code? I'd appreciate the input as I'm quite enjoying working with these boards and might have to think up ideas for my own cars.

Thanks
 

Buzby

Senior Member
Hi Zef,

Yes, there are lots of improvements you can make !.

Firstly, it's difficult to see what the range of each random value is suppposed to be.

Much easier if you do it something like this ....
Code:
symbol RandWrksp  = w2    '  Workspace
symbol RandRange  = w3    '    for
symbol RandResult = w4    '  subroutine

symbol MinResult    = w5    ' Minimum required random result
symbol MaxResult    = w6    ' Maximum required random result

symbol R1 = w7    ' 
symbol R2 = w8    ' Results 
symbol R3 = w9    '


do
    ' Make first random number
    MinResult    = 40000    ' Set Min and Max values for result
    MaxResult   = 40100
    gosub MakeRandom     ' Call subroutine to make result
    R1 = RandResult    ' Update first result
    
    ' Make second random number
    MinResult    = 500
    MaxResult    = 600
    gosub MakeRandom 
    R2 = RandResult    
    
    ' Make third random number
    MinResult    = 20
    MaxResult    = 30
    gosub MakeRandom 
    R3 = RandResult    
    
    ' Show results
    sertxd (#R1," ",#R2," ",#R3,cr, lf)
    
loop
 
' Subroutines
' -----------

MakeRandom:
    RandRange = MaxResult - MinResult + 1
    random RandWrksp  
    RandResult = RandWrksp // RandRange + MinResult
Return
 

Zef

Member
Hi Zef,

Yes, there are lots of improvements you can make !.

Firstly, it's difficult to see what the range of each random value is suppposed to be.

Much easier if you do it something like this ....
Code:
symbol RandWrksp  = w2    '  Workspace
symbol RandRange  = w3    '    for
symbol RandResult = w4    '  subroutine

symbol MinResult    = w5    ' Minimum required random result
symbol MaxResult    = w6    ' Maximum required random result

symbol R1 = w7    '
symbol R2 = w8    ' Results
symbol R3 = w9    '


do
    ' Make first random number
    MinResult    = 40000    ' Set Min and Max values for result
    MaxResult   = 40100
    gosub MakeRandom     ' Call subroutine to make result
    R1 = RandResult    ' Update first result
   
    ' Make second random number
    MinResult    = 500
    MaxResult    = 600
    gosub MakeRandom
    R2 = RandResult   
   
    ' Make third random number
    MinResult    = 20
    MaxResult    = 30
    gosub MakeRandom
    R3 = RandResult   
   
    ' Show results
    sertxd (#R1," ",#R2," ",#R3,cr, lf)
   
loop

' Subroutines
' -----------

MakeRandom:
    RandRange = MaxResult - MinResult + 1
    random RandWrksp 
    RandResult = RandWrksp // RandRange + MinResult
Return
I'll have to check that out when I have more time. Quick look at it makes some sense to me but I've had my head in servo code again.
What I wrote seemed to work ok in simulation but when tested with servos etc it failed to work. What actually happened is only 1 servo per input operated, On power up if the inputs pinC.0 and pinC.1 were off (low) it failed to start moving the servos when pinC.0 and pinC.1 were switched to high (on). I managed to rewrite it to correct it all and apart from a wobble when servo 4 freaked out as there was no variable being fed to it from "wait1". Just my crap coding running out of variables. Still the following code works as I want it to.

Code:
' For Picaxe M18M2
' Servo picaxe
' 1 start operation to control the other
' 4 start operations so they run simultaneously

' Initial servo values are generic until limits are known and can be thus set.

Symbol eyeinput = pinC.0
Symbol guninput = pinC.1
Symbol iris = w1
Symbol eyeV = w3
Symbol gunH = w5
Symbol gunV = w7
Symbol wait1 = w9
Symbol wait2 = w11
Symbol wait3 = w13

start0:
' Send signal to light control Picaxe to turn on Eye light
if eyeinput = 1 then
    high B.7
else
    servo 1,75 ' park the servo at a neutral position
    servo 2,75 ' park the servo at a neutral position
    low B.7
end if
' Check input for gun
if guninput = 1 then
    else
    servo 3,75 ' park the servo at a neutral position
    servo 4,75 ' park the servo at a neutral position
    end if
goto start0

start1:
' Iris Servo, activate the iris servo to open and close the iris at random
if eyeinput = 0 then 'check if input is on or off
      do
          pause 10
      loop until eyeinput = 1
   
    Do
        random w0
        random w8 ' pause length
        iris = w0
        iris = w0//75+45 ' random servo setting
        wait1 = w8
        wait1 = w8//3000+500 ' random delay between movements
        servo 1,iris ' move iris servo
        pause wait1 ' delay before next move
    loop
end if
goto start0

start2:
' Eye Vertical, activate
if eyeinput = 0 then 'check if input is on or off
      do
          pause 10
      loop until eyeinput = 1

    Do
        random w2
        random w10 ' pause length
        eyeV = w2
        eyeV = w2//80+40 ' random servo setting
        wait2 = w10
        wait2 = w10//3000+1000 ' random delay between movements
        servo 2,eyeV ' move eye stalk up/down
        pause wait2 ' delay between movements
    loop
end if
goto start0

start3:
' Gun Horizontal, move the gun horizontally
if guninput = 0 then 'check if input is on or off
      do
          pause 10
loop until guninput = 1   

    Do
        random w4
        random w12
        gunH = w4
        gunH = w4//80+40 ' random servo setting
        wait3 = w12
        wait3 = w12//3000+500 'random delay between movements
        servo 3,gunH ' move servo
        pause wait3 ' delay between movements
    Loop
End If
goto start0

start4:
' Gun Vertical, move the gun vertically
if guninput = 0 then 'check if input is on or off
      do
          pause 10
loop until guninput = 1

    Do
    random w6
    gunV = w6
    gunV = w6//75+45 ' random servo setting
    servo 4,gunV ' move servo
   
    ' quick loop to eliminate servo freaking out if eyeinput isn't running
    if eyeinput = 1 then
    pause wait1 ' delay between movements
else
    pause wait3
    end if
    loop
end if
goto start0
 

AllyCat

Senior Member
Hi,

All your tasks are jumping (GOTO) into the start0: task, which seems "strange". It shouldn't be necessary to use multi-tasking at all, but if you do, I would expect each task to either jump to itself (GOTO its own start: ) , or use the appropriate SUSPEND , RESUME or RESTART commands.

The normal "central" position value of a Servo is 150 ; I believe 75 is the typical endstop position, so using that as a default might cause an overload.

You're probably using some Word Variables where a Byte would be sufficient (but they are needed for correct operation of the RANDOM function). However, you might not be aware that in M2s, in addition to the 13 "normal" Word Variables, there are also six spare "System Word" variables: S_W1 to S_W6 .

Cheers, Alan.
 
Top