Shashank Harshavat sh272                                                                            Norbert Huber nh48

476: Swing

Figure 1: The swing.

Introduction

One day Bruce had an idea. The idea was to build a swing for the 476 Final Project. We took that idea, ran with it, and ended up with this project. The project is based on an Atmel Mega32 MCU. The device consists of a platform mounted in a swing-like fashion. The platform has an attached servo motor that swings a heavy arm. The timing of the arm swing is determined by an accelerometer configured as a tilt sensor. The operation is autonomous. A picture is above in Figure 1. The rest is history.

Rationale

476 Projects are about building cool things that do stuff. Bruce’s idea of the swing was perfect: a simple construction that does something impressive and something that has not been done in lab before. The idea combines microcontroller code with electrical and mechanical components so it is consistent with the spirit of Cornell CDE courses.

Background Math/Physics

The physics and math behind a playground swing are rather simple. We are all familiar with the law of conservation of energy in equation below:

constant

Energy, E, in a closed system is conserved. In an ideal swing, energy is simple converted back and forth from purely potential energy, U, at the ends of the swing, to purely kinetic energy, K, at the bottom of the swing. In our system, we lose some energy to friction, but to make the swing go higher, we are simply adding the potential energy, U, to the swing at appropriate times by raising the center of mass, CM, of our swing. By adding potential energy we are increasing the amount of energy in the swing and therefore make the swing go higher. We can continue to add energy to the swing my lowering the center of mass at the bottom of the swing, where there is no potential energy in the swing to lose.

To initiate the motion, we must force oscillations. The swing can be modeled as a pendulum whose period is given by the equation below:

The period of the swing (assuming small oscillations such as the ones immediately after we initiate the swinging motion), T, is a function of gravity and the length of the swing. We use this equation to force oscillations at the expected frequency in order to get the swing moving.

Reference (and pretty anime): http://www.bsharp.org/physics/stuff/swings.html

Logical structure

The main structure of our design is a feedback control system, as shown in Figure 2:

Figure 2: Feedback Control System

Our control algorithm is a simple proportional controller. We know when we want the servo to move as a function of the position of the swing. When the swing reaches the appropriate position, as senses by the accelerometer, our control algorithm tells the servo to move, which influences the position of the swing, and the feedback loop continues.

The main structure of our electronics is shown below, in Figure 3:

Figure 3: Electronics Block Diagram

The most obvious hardware tradeoffs are cost: our limited cost prevents us from using high-quality, perhaps even custom hinges and other components, so there is trade-off in overall performance and aesthetics in favor of staying within the budget.

The second trade-off is using a servo instead of a solenoid. It turns out that affordable, off-the-shelf solenoids cannot generate enough force to sufficiently alter the center of mass of the swing. As such, we decided to use a servo instead.

The third trade-off is using rigid rods instead of more authentic looking chains for the rods that the electronics sit on. We sacrifice authenticity in favor of a better functioning swing. Had we used chains, the lack of stiffness would have introduced random motion to the swing that would have ultimately removed energy from the swing and decreased our oscillations.

The fourth trade-off is relying on software instead of hardware for much of the control system. We elected to do all the programming and data reading in software instead of relying on hardware amplifiers and comparators. This decision reduced the amount of hardware that had to be built and enables us the convenience of making rapid changes in software.

Relationship to Known Standards (IEEE, ISO, ANSI, DIN, et. al.)

We did not encounter any situations where we needed conform to standards. The nature of our design is independent of standards such as the IEEE standards that govern RF (radio frequency) communication or ISO/ANSI standards that govern video display conventions.

The simplicity of the project, that is, the goal to build something cool that does stuff built from mostly scrap hardware isn’t exactly economically or professionally viable. Our swing swings. That’s it. It is cool that we were able to create an MCU-based swing for virtually no money, but our project remains irrelevant in the world of patents, ™’s, and ©’s.

The 3 elements to the detailed design: mechanical design, electrical design, and software design.

Mechanical Design

The swing is constructed using two metal beams mounted onto a large wooden base. Across the beam is a metal rod which threads through eyehole screws hot glued to two hollow aluminum rods hanging down in parallel. We chose hollow aluminum rods to keep the swing as light as possible in comparison to the oscillating weight. A five-inch by two and half inch Plexiglas plate is attached to the end of the aluminum rods and the electronic hardware is mounted onto it. The Plexiglas is chosen for its non-conductivity. For the weight that is raised and lowered by the servomotor we attached a small cylindrical block of tungsten to a Plexiglas arm, which is also attached to the rotating end of the servomotor. Tungsten is very dense and provides a very compact weight, while the arm is kept long relative to weight to increase the change in potential energy during the operation of the swing. A picture is shown below in Figure 4:

Figure 4: The mechanical design.

Electrical Design

The electronic hardware in the swing design consists of three major components. First is the Mega32 microcontroller mounted onto the custom PC board, which is responsible for control signals and proper timing. Second is the FreeScale MMA1260 Z-axis, 1.5g Acceleration Sensor that acts as a tilt sensor to monitor the position of the swing. The sensor provides around 4V when completely level to the ground and then decreases its output as it is tilted. Finally there is the S03N GWS servomotor, which lifts and lowers a weight up to 60 degrees in either direction to provide energy to the swing. To control the direction of the motor, the control line needs a 20ms period control signal with varying pulse widths for each position of the motor. The servomotor is used due to its adequate torque and its smooth transition. The acceleration sensor is attached to the custom board and its output is connected to the A0 pin of the MCU so the onboard ADC on the Mega32 can sample the sensor signal. The connecting wire is kept short to minimize electrical noise that may corrupt the signal. The B0 pin of the microcontroller provides the control signal for the servomotor but to ensure that sudden discharges from the servo do not damage the Mega32, the pin is buffered from the servo control line with a 4N35 optoisolator. Also, two DC supplies of 12V and 5V are used to power the MCU and servo respectively to ensure isolation. The sensor is powered at 5V by tapping the converted voltage off of the custom board’s power regulator.  The wiring of the accelerometer is trivial. The schematic of the optoisolator circuit is shown below in Figure 5. An image of the PCB and accelerometer is shown in Figure 6.

Figure 5: The optoisolator schematic.

Figure 6: The PCB.

Software Design

The electronic hardware in the swing design consists of three major components. First is the Mega32 microcontroller mounted onto the custom PC board, which is responsible for control signals and proper timing. Second is the FreeScale MMA1260 Z-axis, 1.5g Acceleration Sensor that acts as a tilt sensor to monitor the position of the swing. The sensor provides around 4V when completely level to the ground and then decreases its output as it is tilted. Finally there is the S03N GWS servomotor, which lifts and lowers a weight up to 60 degrees in either direction to provide energy to the swing. To control the direction of the motor, the control line needs a 20ms period control signal with varying pulse widths for each position of the motor. The servomotor is used due to its adequate torque and its smooth transition. The acceleration sensor is attached to the custom board and its output is connected to the A0 pin of the MCU so the onboard ADC on the Mega32 can sample the sensor signal. The connecting wire is kept short to minimize electrical noise that may corrupt the signal. The B0 pin of the microcontroller provides the control signal for the servomotor but to ensure that sudden discharges from the servo do not damage the Mega32, the pin is buffered from the servo control line with a 4N35 optoisolator. Also, two DC supplies of 12V and 5V are used to power the MCU and servo respectively to ensure isolation. The sensor is powered at 5V by tapping the converted voltage off of the custom board’s power regulator.

All timing in the software is controlled by the timer0 compare interrupt. The clock is prescaled by 64 and the OCR0 is set the to 67. The choice of OCR0 was the result of trial and error starting with 250, then 125, and finally 67. The operation of the swing is divided into three stages. Because the sensor is very inaccurate at low-level amplitudes, we programmed two initial stages that can boost the swing up to amplitude more appropriate for sensor operation. The initial stage is split into two 12-second stages because the swing exhibits different fundamental resonance frequencies at low and medium amplitudes. A long int called initcount is used to count out the 24-second cycle. The interrupt updates initcount while still in the first two stages of operation and uses if else branches to control desired operation. In automatic mode the interrupt toggles a flag variable wait at half the resonance period. When wait is toggled back to zero, if else branches update the char variable width with one of two values. These values correspond to the number of cycles needed to produce .85ms pulses and 2.1ms pulses, which are the correct widths for the extreme positions of the motor. The char variable flip is also toggled every time the width is updated so the interrupt knows to alternate widths. Once the width is set, the interrupt uses the pulsecount variable to time the appropriate sized pulse and output it to B0. The B0 pin is initially high, is set to zero when pulsecount equals the width, and resets to one once pulsecount has counted out 20ms. In the sensor mode the wait flag is set for a much smaller period of time and is not set high again until the width variable is changed. This prevents noise from the sensor readings causing the width to be updated sooner than desired and prevents the motor from triggering rapidly in a small periods of time. Also in sensor mode, the width is updated according to an algorithm rather than automatically after a period of time. The read() function, which is timed by the interrupt and the variable time1 and is called by the main function, reads the ADC samples every 100 cycles. It stores ADCH into Ain0 and then sets ADSCR.6 high to start another conversion. The function also stores the previous 7 samples in Ain1-7. All these 8-bit samples are cast to int’s and summed together. Then the sum is right shifted by three to divide by 8 and find the average of the samples to be stored as the variable tilt. This process acts as a moving average filter in an attempt to filter out random noise that can corrupt the sensor signal.  The read() function also stores the previous two tilt values for use in the triggering algorithm in the interrupt. While in sensor mode the interrupt checks to see if tilt is below a certain threshold which indicates swing is in the center position of its range.  If this is true and if tilt has either stayed the same for the previous two cycles or has increased over time, we know that the swing is in one of the extreme positions of its range or is falling. Then width is updated to the opposite value and the motor swings the weight 120 degrees to the opposite extreme.

Problematic Design Elements

The solenoid approach did not generate enough change in the center of mass to generate the swinging motion.

The accelerometer does not have enough resolution to work at low amplitudes.

Speed of Execution

In the end the swing worked better than we had hoped. The autopilot stages worked extremely well in getting the swing to moderate amplitudes and once the sensor mode kicked in the swing really started to fly. We had to turn off the swing just for fear that the swing might swing completely around and break some wiring.

Accuracy

The sensor works well at larger amplitudes but is completely unreliable at lower amplitudes. If a more sensitive sensor was utilized we could imagine not having to use the autopilot stages at all. The simple moving average filter we utilized to de-noise the sensor signals turned out to work pretty well. We found no need to incorporate a more sophisticated filter, as this would have just eat up computation time.

Our initial approach for the swing utilized a solenoid to raise and lower the entire circuit. The problem with this approach was the solenoids were very weak and didn’t move the weight very far so our change in potential energy was very small. Also the solenoids motion was very jerky and this caused sudden vibration on the swing that both disrupted the sensor and also disrupted the swinging motion. Bruce and another one of the swing groups suggested we switch to a servo. By changing to the servo, we were able to lift much more weight for larger range of motion with very smooth transition. Regretfully we did burn out one servo due to overloading. Other than that the servo turned out ideal.

Design Safety

As far as safety, we always made sure for high amplitudes to never stand in the path of the swing or point the swing at any other groups. We made sure everything that could potentially fly off was firmly attached to the swing. Repetitive noise from the servo may have annoyed some of the groups working next to us so we apologize. Still in the end, I think the fully functional swing gave the other groups something interesting to look at while they were taking a break from their own work. No one was hurt in the process of making this swing.

Interference (e.g. CPU noise, RF noise)

We had no relevant interference issues with other groups.

Usability

The simplicity of our design allows anybody to simply walk up to the swing, flip the switches, and stand back to watch it go. Although the design required the information obtained throughout educational experience, the final product is as simple as a child’s toy.

Result Analysis

Our swing works a lot better than expected. Our initial use of a solenoid was disappointing at best, but the consequences of the consequent use of a servo were surprising. We are happy that we did not need to implement a more elaborate control system. It is nice to know that the swing generally worked more or less as we originally intended it to.

Our results exceeded our expectations: we were able to get excellent performance without any additional elaborate software or hardware. We even have an icing on the cake since we will attempt to swing in a full circle during the demo.

For next time, replaced the rigid rods with chains would make the swing more authentic. We could also make the swing prettier and add flare by including buttons to control the maximum amplitude, for example. To make things interesting, we could turn this into a dynamics and feedback problem by creating a swing that starts from a standstill and ends balancing itself upside-down at the top of the swing. Unfortunately, I believe that this interesting project would be outside of the budgetary constraints of the project.

Intellectual Property Considerations

Intellectual property is effectively nonexistent in the design of our project. In terms of mechanical design, we built a scale model of a common playground swing, which lacks significant science behind such construction. In terms of electrical and software design, the circuits and code use elementary principles that can be found in any physics textbooks. There are even two other groups this year constructing very similar swings. Therefore, there are no patent opportunities. We did not reuse code, use an existing design, or signed any NDAs.

Ethical Considerations

In the context of the IEEE Code of Ethics, all the claims made in this report are supported by the operational swing (Rule 3); we elected not to sell our project to one of the other swing groups (Rule 4); we were qualified to use all tools and components involved in the project (Rule 5); we incited constructive criticism from Bruce, his team of TAs, and fellow students and noted all external contributions (Rule 7); and we encouraged the open use of our power-tools by other groups (Rule 10).

Special Thank You

We’d like to thank Bruce for the idea itself and his general ability to kick ass and fix all of our problems. We’d like to thank the TA’s, especially Gus wasting multiple hours diagnosing our ignorant problems. Most of all, we’d like to thank Konstantin Klitenik for providing back up servos and for being our personal project consultant in the late stages of the project. Without these people, our swing just would not swing.

Appendix A: Code

#include <Mega32.h>

#define begin {

#define end }

#define t1 100

//12 seconds

#define init 44776

//24 seconds

#define init2 89552

void initialize(void);//initialization stage

//variable declarations

unsigned char time1,Ain0,Ain1,Ain2,Ain3,Ain4,Ain5,Ain6,Ain7;

unsigned int temp,count;

unsigned char tilt,oldtilt1,oldtilt2,wait,flip,pulsecount,width;

long int initcount;

//interrupt drives timing for read() function and times out different

//stages of swing operation

//first stage swings automatically at low amplitude period for 12 seconds

//secod stage swings automatically at medium amplitude period for 12 seconds

//third stage uses sensor to trigger the motor at ideal time

interrupt [TIM0_COMP] void timer0_compare(void)

begin

//iterate timer variable for read() function

time1--;

//iterate init counter while still in auto mode

if(initcount <= init2) initcount++;

//time wait flag to halt operation for number of cycles

if(wait == 1) count++;

if(initcount >= init2)//sensor mode

begin

if(tilt < 195 && tilt <= oldtilt1 && oldtilt1 <= oldtilt2 && wait == 0)//detect extreme postion if not halted by wait flag

begin

if(flip == 0)

begin

width = 8;

PORTD.7 = 0;

flip = 1;

end

else

begin

width = 3;

PORTD.7 = 1;

flip = 0;

end

wait = 1;//set wait to halt further action

end

end

else//if not in sensor mode dont detect extreme position, just trigger motor when not halted by wait

begin

if(wait == 0)

begin

//use flip variable to alternate direction of servo movement

if(flip == 0)

begin

//update pulse width for control line and light LED for debugging

width = 3;

PORTD.7 = 0;

flip = 1;

end

else

begin

width = 8;

PORTD.7 = 1;

flip = 0;

end

wait = 1;//set wait to halt further action

end

end

//create pulse for servo motor conrol with appropriate width

if(pulsecount == 74)//74cycles counts up 20ms periods

begin

PORTB.0 = 1;

pulsecount = 0;

end

else if (pulsecount == width)

begin

PORTB.0 = 0;

end

pulsecount++;

if(initcount <= init2)

begin

//first stage trigger servo every half low amplitude period

if(initcount <= init)

begin

if(count >= 2487)

begin

wait = 0;//resume

count = 0;

end

end

else//second stage trigger servo every half med amplitude period

begin

if(count >= 2568)

begin

wait = 0;//resume

count = 0;

end

end

end

else//sensor stage, just prevent rapid triggerings of motor

begin

if(count >= 1200)

begin

wait = 0;//resume

count = 0;

end

end

end

void main(void)

begin

initialize();

while(1)

begin

end

end

begin

time1 = t1;

//store previous 7 values

Ain7 = Ain6;

Ain6 = Ain5;

Ain5 = Ain4;

Ain4 = Ain3;

Ain3 = Ain2;

Ain2 = Ain1;

Ain1 = Ain0;

//get new sample

//add all samples and divide by 8 to average

temp = ((unsigned int)Ain7 + (unsigned int)Ain6 + (unsigned int)Ain5 + (unsigned int)Ain4 + (unsigned int)Ain3 + (unsigned int)Ain2 + (unsigned int)Ain1 + (unsigned int)Ain0);

temp = (temp>>3);

//store previous two averages for interrupt algorithm

oldtilt2 = oldtilt1;

oldtilt1 = tilt;

tilt = temp;

//start another conversion

end

void initialize(void)

begin

DDRB=0xff;

DDRD= 0xff;

TIMSK=2;       //turn on timer 0 cmp match ISR

OCR0 = 67;     //set the compare re to 67 time ticks

TCCR0=0b00001011;    // clock/64 and enable interrupt

//init count variables

pulsecount = 0;

time1 = t1;

temp = 0;

flip = 0;

initcount = 0;

//init the A to D converter

//channel zero/ left adj /int Aref

//enable interrupts

#asm

sei

#endasm

end

Appendix B: Schematics

Optoisolator Schematic

Appendix C: Parts List

 Parts Quantity Cost Atmel Mega32 Microcontroller 1 8.00 Custom PCB 1 5.00 MMA1260D Accelerometer 1 Sampled 4N35 Optoisolator 1 Free (lab) Power Supply 2 10.00 Solder Board 1 2.50 Servo Motor 1 10.00 Swing Frame 1 Free (scrap) Swing Aluminum rods 2 4.00 Swing Hooks 2 1.00 Tungsten Ball 1 Free (lab) Plexiglas 1 Free (scrap) Various resistors and capacitors Free (lab) Various plastic parts and stuff Free (scrap) TOTAL COST 40.50