Halloween Forum banner

1 - 20 of 44 Posts

·
Registered
Joined
·
40 Posts
Discussion Starter #1
Hi folks,
I'm trying to write Arduino code for essentially a 3-Axis skull. I followed the "Jawduino" build from ButtonBanger.com but I tweaked it to run from a PIR sensor. Now I'm trying to add extra servo sequences (just random motions), but I'm having an issue running the servos at the same time as the talking sequence. I don't know how to code several servos to run at once. I'm also using the variable speed servo library which allows me to slow down individual servo speeds. Any help would be great!
 

·
Registered
Joined
·
3,324 Posts
I'm not an Arduino guy (I use PIC's) but I don't think it can execute more than one command at a time. To do multiple servos at the same time would need an Arduino for each servo. You may wanna look into the Pololu Mini Maestro for doing the 3-axis portion.
 

·
Registered
Joined
·
40 Posts
Discussion Starter #3
Hi J-Man, thanks for your response! You're right that the arduino can't technically loop more than one function but apparently you can use the loop to read millis () and then have the program call functions that have action code outside the loop at specific times (which are dictated by the millis reading). I understand the concept but I am brand new to coding and I don't know how to replace what I want it to do into existing code examples of multiples at once...they usually are blinking LEDs. I found one that incorporates a servo sweep but I don't know how to integrate that into a code with a talking servo connected to an analog input of a soundboard. Not to mention with a PIR sensor, and MP3 player!
 

·
Registered
Joined
·
3,324 Posts
Again I'm not familiar with Arduino code but the bottom line is that if the program is tied up driving the jaw servo, I don't think it can task other outputs.
 

·
Registered
Joined
·
40 Posts
Discussion Starter #5
sigh You're probably right. But I might be able to code the talking portion as a call to a function and pull that out of the loop too (the code is really only about 2 lines). If I can figure out a way to do that I know that I can start the sequence with an input from the PIR --> play a random audio file from the MP3 --> trigger read/write from the audio signal to Jaw Servo and randomize other servos simultaneously. At the very least I could have one Arduino run the PIR, Jaw Servo and MP3 (that's what I have now) and run another Arduino to randomize the other servos (according to the code that I found).
 

·
Registered
Joined
·
3,324 Posts
Trust me on this, I've been down that road with my own skulls. You need a dedicated controller for just the jaw sync. Then you need either a controller with a multi cog processor or an Arduino for each of the 3-axis servos. Using a multi cog processor, (or 3 Arduinos) the program for random movement of 3 servos is quite complicated. You have to provide the min and max positions for each servo, (using a servo tester), the program has to access the last position of each servo before it can generate the next move, and last but not least, each servo has to be continually refreshed every 20ms. Not an easy program by any means.
 

·
Registered
Joined
·
229 Posts
A single micro (PIC or AVR on Arduino) can effectively run heaps of processes effectively in parallel from the user's prospective. Controlling a few servos is not hard for someone experienced in programming. For an Arduino you'd have to find suitable libraries that take care of that for you. I use Arduino Nano modules for some of my props, but almost never use the Arduino IDE. I tend to program in C (in Atmel Studio 7) and do the low level stuff myself. One of my projects uses a PIC to receive DMX and control 5 servos at the same time.
 

·
Registered
Joined
·
3,324 Posts
A single micro (PIC or AVR on Arduino) can effectively run heaps of processes effectively in parallel from the user's prospective. Controlling a few servos is not hard for someone experienced in programming. For an Arduino you'd have to find suitable libraries that take care of that for you. I use Arduino Nano modules for some of my props, but almost never use the Arduino IDE. I tend to program in C (in Atmel Studio 7) and do the low level stuff myself. One of my projects uses a PIC to receive DMX and control 5 servos at the same time.
If you have a way to control multiple servos simultaneously from a single core micro, kudos to you because I don't see how it's possible. A single core processor can only carry out one command at a time.
 

·
Registered
Joined
·
229 Posts
The trick is to do the servo work in timer interrupts. Here's how I did it with 5 servos and 2 interrupts. It works because the total on time of all servos is less than the refresh period.

Every 20ms you start the first servo's output via the refresh interrupt. You set the pulse width timer to the on period for that servo. When that interrupt fires at the end of that time, switch the servo off, start the next servo and set the interrupt timer for the next pulse width. This continues until all servos have been pulsed. Then you wait for the next 20ms refresh tick.

All of this as well as DMX reception is ticking along in the "background" with the main loop just updating the servo pulse values if required.
 

·
Registered
Joined
·
3,324 Posts
Again, that's not controlling multiple servos simultaneously, that's doing one at a time. And I'm not following how 5 servos one at a time can each be set to a new position within 20ms, am I missing something?
 

·
Registered
Joined
·
229 Posts
With that method, all 5 servos get updated withing the same 20ms period, but you're right they are not updated at exactly the same time. The first to last update time is still only around 10 ms.

To update them all simultaneously, you could start all outputs at the same time then drop them off at whatever pulse width they each need. To do that with 8-bit you'd need to either call the pulse interrupt every 2us to compare the pulse width counters for each servo. Since each output would have a 0.5ms fixed minimum, you can do that first for all outputs.

Another way to do it is dynamically set the next interrupt event and have a bit mask to tell you what output to turn off. There would be even more ways of doing it I'm sure. There's no need for more than one micro to control multiple servo outputs, but that would be an easier solution if you don't want to get into more advanced interrupt use.
 

·
Registered
Joined
·
3,324 Posts
I understand your theory on this but I still do not see how you could RANDOMLY control a 3-axis skull with a single core micro when each servo positon needs to be refreshed every 20ms. If you could pull that off and get fluid movement you are the programming guru of all gurus!
 

·
Registered
Joined
·
3,324 Posts
Let me put that another way. In a 3-axis skull, lets say the random movement that's generated involves the nod servo to move from 1000us to 2000us and the pan servo to move from 1800us to 1100us and take 2 seconds to complete the move. At the same time, monitor the jaw sync and execute those required movements, AND refresh all of the servos every 20ms. How does a single core micro pull that off?
 

·
Registered
Joined
·
3,324 Posts
Would this not be better achieved with something can have multiple threads? Such as a Raspberry Pi
That's what I've been saying, a processor with multiple cogs. A talking 3-axis skull needs one dedicated core to monitor the audio for jaw sync. Another cog for each of the 3-axis servos. If David_AVD has written code that can successfully accomplish this using one single core micro then my hats off to him, that's some pretty amazing code.
 

·
Registered
Joined
·
210 Posts
That's what I've been saying, a processor with multiple cogs. A talking 3-axis skull needs one dedicated core to monitor the audio for jaw sync. Another cog for each of the 3-axis servos. If David_AVD has written code that can successfully accomplish this using one single core micro then my hats off to him, that's some pretty amazing code.
No matter whether or not you can do it, does not mean it is the right tool for the job. I would rather spend $35 for a Pi than spend days coding something. My time is worth more than the money.
 

·
Registered
Joined
·
229 Posts
Multitasking on a microcontroller is not much different to on a PC, a Raspberry pi, etc. The processor is executing instructions so fast that it can switch tasks thousands of times per second.

When microcontroller code (including for Arduino) is written with delay functions and other blocking code, that wastes CPU cycles twiddling it's digital thumbs. Code written as event driven is expandable, easily debugged, etc. The main loop should have very little in it. I typically have some bit flags I test so I can run short functions as they are required. These functions each do one small task. Those flags can be set by other functions or in an interrupt. They get cleared by the function when it runs.

For example, why sit in a tight loop (blocking other processes) waiting for a trigger input? Scan for the input state every 50ms and act upon it (set a bit) only if the state has changed since the last scan. That's event driven. In between those input scans, you can be updating a bunch of servo outputs, toggling an LED, sending commands to an mp3 module, or whatever you need.

Commercial prop controllers do the same thing. They are controlling lots of outputs, timing stuff, watching for input triggers, etc all effectively at the same time as far as the user is concerned. I'm sorry if I'm not explaining this well enough, but I can assure you that a single micro can do an amazing amount of processing when coded correctly.
 

·
Registered
Joined
·
3,324 Posts
Multitasking on a microcontroller is not much different to on a PC, a Raspberry pi, etc. The processor is executing instructions so fast that it can switch tasks thousands of times per second.

When microcontroller code (including for Arduino) is written with delay functions and other blocking code, that wastes CPU cycles twiddling it's digital thumbs. Code written as event driven is expandable, easily debugged, etc. The main loop should have very little in it. I typically have some bit flags I test so I can run short functions as they are required. These functions each do one small task. Those flags can be set by other functions or in an interrupt. They get cleared by the function when it runs.

For example, why sit in a tight loop (blocking other processes) waiting for a trigger input? Scan for the input state every 50ms and act upon it (set a bit) only if the state has changed since the last scan. That's event driven. In between those input scans, you can be updating a bunch of servo outputs, toggling an LED, sending commands to an mp3 module, or whatever you need.

Commercial prop controllers do the same thing. They are controlling lots of outputs, timing stuff, watching for input triggers, etc all effectively at the same time as far as the user is concerned. I'm sorry if I'm not explaining this well enough, but I can assure you that a single micro can do an amazing amount of processing when coded correctly.
At the risk of beating a dead horse, I agree that proper coding can do a lot BUT, you haven't addressed the example I gave above. Executing servo refresh between scanning for an input trigger is easy, executing what I have outlined above, not so easy, maybe not even possible. Again, if you can pull that off, you are without a doubt one of the worlds best programmers for sure. 🎃
 
1 - 20 of 44 Posts
Top