Help with creating a random routine for project

agroom

New Member
First a quick background of my project. It's a remake of an "analog" laser spirograph I made a few years back. 4 small motors are setup with mirrors glued to the end. A laser is then reflected off each mirror. Varying the speed of each motor creates new designs. In this version the motors are wired up directly to pots. The new "digital" version I'm making uses a 20M2 where each pot is read into the MCU and the motors are controlled by PWM. It's also got a 16x2 LCD display and has has 4 modes:
  • Manual - The user directly controls the motor speeds (0-10) with one of 4 pots. If there's a design they like, then can "Save to Favorites" which writes the 4 motor speeds to EEPROM.
  • Favorites - Allows the user to browse, display and delete their saved favorites.
  • Auto-Favorites - An "unattended" version of Favorites mode that just cycles through all their favorites automatically.
  • Random - Just randomly picks motor speeds and displays them.
The only inputs are the 4 motor speed pots, a single select button (uses short & long press) and a 5th pot for selecting modes, etc. So far I've got the first 3 modes working great, but I'm having issues creating an algorithm for the random mode. Here's where I'm hoping someone might have some ideas or insight :)

The problem I'm having is that the best designs usually come from only 2-3 motors running (or all 4 with 1-2 set very slow). But I also don't want to exclude having it run all 4 at higher speeds either, just not as often. Also, I'd like the transitions between designs to look/feel organic and not jumps between two completely different designs.

Ideally I kind of envision it starting on a design and holding for about 1s. Then it morphs into another completely different design, hold about 1s then repeat. I'm thinking I'd also like to have the morph time dependent on the user, so they can have it very quick to very slow, or an "auto" where it's random. This would be done with the selector pot.

Here's just some ideas I've tried and what I like and don't like about them:

My first attempt I just tried randomly choosing motor speeds. This looked okay, but I ended up getting those "jumps", which is why it's now part of my criteria. It also didn't account for more instances of only 2-3 motors running.

To fix the "jumps" I tried giving each motor two attributes, current speed and target speed. Each cycle it would increase/decrease the current speed until it hit the target speed, in which case it would assign a new random target speed. Rinse/repeat. This worked "okay" but it tends to not have much variation. Since each motor is constantly moving towards a target speed, they all tend to cross in the middle. It also seemed very unlikely that some combinations of speeds would essentially never be executed.

Finally I just decided to just try 4 embedded FOR loops that would cycle through EVERY possible combination. I liked the output on this, but with a total of ~14,500 possible combinations (11^4), you'd realistically never get to most of them. Also, the variations between iterations were so minor that it took a while before new designs came about.

Note: Although it has 10-bit PWM, variations between, say 234 and 235, are so inconsequential I went with having just 10 discrete speeds. The motors also wouldn't start turning until about ~270, and after about 80% duty, there was little to no noticeable difference. So my PWM output is calculated by PWM = Speed (1-10) * dutyStep (50) + dutyMin (300) or 350-800.
* An exception is made if speed = 0 since it would still produce a PWM of 300.

[EDIT] I forgot to mention, it might also be fun to create 2-3 different random algorithms that the user can choose between, with each having a different kind of "style". For instance, the first example of just picking random speeds would be fine if implemented with others.
 

inglewoodpete

Senior Member
The motors also wouldn't start turning until about ~270, and after about 80% duty, there was little to no noticeable difference. So my PWM output is calculated by PWM = Speed (1-10) * dutyStep (50) + dutyMin (300) or 350-800.
You should be able to get a wider range of motor speeds by giving the motors a short burst of just a few milliseconds of 100% and then drop back to a smaller PWM value. I have used this method in the past to overcome the starting inertia of motors..

I don't have access to UTube at work, so most of your project is still a mystery to me.
 

westaust55

Moderator
In the same manner as IWP suggests.
Many commercial motor soft starters and variable speed drives put out a user set pulse at motor start-up to overcome he initial inertia and friction. Otherwise the operator may think the motor is not starting and may do something unsafe. Also prevents a "Jack-rabbit" start when the output ramps up and is finally sufficient to start the motor turning.
 

agroom

New Member
You should be able to get a wider range of motor speeds by giving the motors a short burst of just a few milliseconds of 100% and then drop back to a smaller PWM value. I have used this method in the past to overcome the starting inertia of motors.
I tried an implementation of that in an earlier version of my code. It seemed to work okay, but it just didn't work as well as I expected. Either I just wasn't doing it well, or speeds below 300 just weren't very noticable like when going past 800. Thanks for the tip though!
 
Top