Random Servo pulse generator code

Using the atom 28 or pro28 how can i program random Servo movements…
with …
limits on the move delay (time between moves) say 3-10 seconds.
limits on the travel time (speed) say up to 3 seconds
limits on the servo range (angle) say +/- 30°?

Thanks in advance guys.

Generate a random number scaled to the desired range.

Alan KM6VV

Humm, yes thats what i need help with.
Just wondered if there was any examples about?

The plan is to either use the BA28-P28 or just a SSC-32 if it can work as a stand alone controller only controlling up to say 8-9 servos?
Id like to switch on the power then have the servos moving randomly, but id also like to individuality limit the servos travel, end times, speed and even maybe how frequently they are commanded as explained before.
Is there any way of doing this?

Its always these simple programming bits that get me. :blush:

Random is well, random… What you probably want is a pseudo random set of values to send to a movement system.

Each channel would have a set of values for:

Delay between moving.
Movement speed.
Movement position.

Each value would have a valid range defined.

Now you have some rules for the “randomness” and you can code it. I would seed the random number generator with a value based on a timer and a switch press. After the numbers are gathered you simply mathify them to be in the required range. You could then wrap it all up in a program that randomizes which servo to move.

he Atom Pro’s random function generates a 32 bit (long) from the seed value. The manual suggests basing the random number on a timer (timer A), then use that number as a seed for the final random number.

a var long a = random TCA a = random a

You can wrap this in a subroutine to get a new random number each time it is entered. Now we need to scale the results to usable values. We tried it with this code. Note, I see a lot of duplicates…

a var long main a = random TCA a = random a serout s_out, i38400, [dec a, 13] pause 20 goto main

66358
131538
130
10
196862
131406
522
131538
130
65846
132050
642
522
131538
131918
30
132050
642
66358
131538
130
10
196862
131406
522
131538
131918
30
132050
642
522
131538
131918
30
132050
131406
542
131526
130
10
132050
131406
542
131538
130

However changing the code to this.

a var long a = random TCA main a = random a serout s_out, i38400, [dec a, 13] pause 20 goto main

Results in values like this.

1023555307
2048158937
4113160612
3931353674
3568788615
2826881296
1374458402
2732139607
1169377456
2339869026
402596566
787432639
1557039488
3096253186
1880761879
3760540721
3242956916
2189832682
68969414
154715807
309431617
618863252
1238840363
2461952344
611177138

So now if any of the real smart guys wants to jump in… :wink:

My first gut instinct tells me to convert the numbers to a fraction and multiplying by the range.

The values:

1023555307
2048158937
4113160612

Convert to:

.1023555307
.2048158937
.4113160612

Then for servo position you do this math.

servo_position = (rand_no x 2000) + 500

The conversion would be something like this.

while rand_no > 1 ? bit shift ?

Riley and Devon suggested modulus but I don’t understand it.

servo_pos = (rand_no // 2000) + 500

Helping? :stuck_out_tongue:

thanks for taking the time posting that.

lol, i don’t really understand any of it. lol

iv been writing up routines like:

[code];GOSUB Simulations
FastBlink
hservo [BlinkPin-11500\0]
pause 50
hservo [BlinkPin\0\0]
return

SlowBlink
hservo [BlinkPin-11500\100]
pause 1000
hservo [BlinkPin\0\100]
return

SlowNeckRotateLeft
hservo [NeckRotate_Pin\10000\100]
return

SlowNeckRotateRight
hservo [NeckRotate_Pin-10000\100]
return

OpenWingsSlow
hservo [LWingPin\10000\100]
hservo [RWingPin\10000\100]
return

OpenWingsFast
hservo [LWingPin\10000\0]
hservo [RWingPin\10000\0]
return

CloseWingsSlow
hservo [LWingPin-10000\100]
hservo [RWingPin-10000\100]
return

CloseWingsFast
hservo [LWingPin-10000\0]
hservo [RWingPin-10000\0]
return

PitchWingsUPSlow
hservo [WingsPitchPin\10000\255]
return

PitchWingsUPFast
hservo [WingsPitchPin\10000\0]
return

PitchWingsDOWNSlow
hservo [WingsPitchPin-10000\255]
return

PitchWingsDOWNFast
hservo [WingsPitchPin-10000\0]
return

BeakSnap
hservo [BeakPin\10000\0]
pause 100
hservo [BeakPin\0\0]
return [/code]

Using the Hservo Driver:

[code] hservo [BlinkPin\ (BlinkPosition1stepsperdegree1)/100 + Blink_Offset_mBlinkSpeed, |
RWingPin\ (RWingPosition1
stepsperdegree1)/100 + RWing_Offset_mRWingSpeed, |
WingsPitchPin\ (WingsPitchPosition1stepsperdegree1)/100 + WingsPitch_Offset_mWingsPitchSpeed, |
LWingPin\ (LWingPosition1
stepsperdegree1)/100 + LWing_Offset_mLWingSpeed, |
BeakPin\ (BeakPosition1stepsperdegree1)/100 + Beak_Offset_mBeakSpeed, |
Neck_UpperF_Bpin\ (Neck_UpperF_BPosition1
stepsperdegree1)/100 + Neck_UpperF_B_Offset_mNeck_UpperF_BSpeed, |
Neck_UpperL_Rpin\ (Neck_UpperL_RPosition1stepsperdegree1)/100 + Neck_UpperL_R_Offset_mNeck_UpperL_RSpeed, |
Neck_LowerF_Bpin\ (Neck_LowerF_BPosition1
stepsperdegree1)/100 + Neck_LowerF_B_Offset_mNeck_LowerF_BSpeed, |
Neck_LowerL_Rpin\ (Neck_LowerL_RPosition1stepsperdegree1)/100 + Neck_LowerL_R_Offset_mNeck_LowerL_RSpeed, |
NeckRotate_pin\ (NeckRotate_Position1
stepsperdegree1)/100 + NeckRotate_Offset_mNeckRotateSpeed]

return
[/code]

But again im just playing with code already available.

Just typed this up in notepad, downloaded the studio and tested it. This code spits out random servo pulses ranged 500 - 2500.

[code]randn var word
a var word
a = random TCA

range var word
minvalue var word

;define the working range you want
range = 2000

;define the smallest number in the range
minvalue = 500

main
gosub Gen_random
serout s_out, i38400, [dec randn, 13]
pause 100
goto main

Gen_random
a = random a
randn = (a // range) + minvalue
return[/code]

Oh devon. You are a genius. Thank you.
Now to order another board and chip. Lol

Agree, that is really a brilliant way to solve this issue.

For better understanding of the modulo operation these two lines give the same result (as long as a/range return an integer):

randn = (a // range) + minvalue randn = (a - (range * (a/range)))+ minvalue

If a = 1999 the remainder would be this value since the division of 1999/2000 return 0, so the result would be 2499 (1999+500).

This mean that if you want the range to be exactly 500 - 2500 the range variable should be set to 2001 and minvalue = 500.

The reason for why I’m posting this is that I didn’t understand the modulo // operation either.

Thanks to Devon for learning us programming smarter! :smiley:

Yep - The fun part at times is getting it random from one run to another. I see he initialized the first seed to TCA which should hopefully be reasonably sufficient, but as the program takes more or less the same time to start up from one run to the next could potentially have very similar results from one run to the next…

On the Arduino, one approach they mention is to use an analogRead of an unconnected IO pin as the seed. randomSeed(analogRead(0));

Also they already built the range code into it for you. If you want values 500-2500 (both inclusive), you could simply do:
myval = random(500, 2501);

Kurt

I also suspect the same thing can be used for random speed and random servo movement delays?
Some of the code ill be using canned sequences and its great to be able to have random movements running along side this. Thank you.

wisper (botborduino)

Very large :smiley:

I don’t actually know much about basic, so I used the same seed as innerbreed in his previously posted snippet. As kurte said, using an analog pin as a seed is usually what I do when using the random function on my arduino projects. Again like kurte said, the board is pretty much going to start up exactly the same every time so I always stuck a delay into the setup so I wouldn’t get the same number every time for the first read.

p.s. The idea to use the modulus operator came from Riley so I shouldn’t get all of the credit. :wink:

… large … ?

?

once i grab a board i can start testing this. thanks again for the heads up. very interested to see it working. :smiley: :smiley:

Um, I was smiling a big smile that Jonny finally got his code bits sorted.

Lol. Cheers.