element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Hack the Holidays
  • Challenges & Projects
  • Project14
  • Hack the Holidays
  • More
  • Cancel
Hack the Holidays
Hack the Holidays Blog Art in Motion: Snoopy’s Christmas P.O.V. , singalong and Dogfight Animatronics
  • Blog
  • Forum
  • Documents
  • Leaderboard
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Hack the Holidays to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: robogary
  • Date Created: 9 Jan 2023 4:46 PM Date Created
  • Views 2575 views
  • Likes 16 likes
  • Comments 6 comments
  • robogary
  • project14
  • hacktheholidaysch
Related
Recommended

Art in Motion: Snoopy’s Christmas P.O.V. , singalong and Dogfight Animatronics

robogary
robogary
9 Jan 2023
Art in Motion: Snoopy’s Christmas P.O.V. , singalong and Dogfight Animatronics

I was inspired to do a project this year that was nostalgic and artistic; highly visual, musical, entertaining, and inspirational.

The visual message was chosen to be persistence of vision (P.O.V.) based since I’d never tried that before.

The project was originally going to be a P.O.V. angel for the treetop, but the first prototype ended up being too big, too heavy, and too off balance to go there. That idea didn’t really get my creative juices flowing. Maybe next year for that idea……..

I thought about the music portion of the project.  Rifling through my Christmas music collection I came across the Snoopy’s Christmas album by The Royal Guardsman 1967. Nostalgic and fun, it struck a chord. (nyuk nyuk nyuk) so here we go…..

Table of Contents:

Concept Spec

Project videos and photos

Implementation Description

Build materials

Electrical schematics

Code for 2 Arduinos and 1 Raspberry Pi Pico

challenges & compromises

The Concept Spec:

  1. 3 tunes were selected to be played by the Snoopy’s Christmas POV project:
  • Snoopy’s Christmas 1967
  • Snoopy VS Red Baron 1966
  • Excerpt from Merry Christmas(War is Over) 1971
  1. The P.O.V. would be multiple holiday messages displayed in sequence, with Snoopy appearing to hold them. Ooooooo this is going to be magical.
  2. …….The “coup de grace” build miniatures of the Red Baron and the Sopwith Camel circling the P.O.V. display while dogfighting.

 

All these actions and motions operate simultaneously.

The Project:

You don't have permission to edit metadata of this video.
Edit media
x
image
Upload Preview
image

4 minute demo video with music tracks

You don't have permission to edit metadata of this video.
Edit media
x
image
Upload Preview
image

1.75 minute demo video video without music tracks

Project Photos:

image

image

image

image

 image

image

image

image

 

 

Implementation Description:

The project consists of multiple rotating sub systems. The subsystems need to be modular and self contained (likely battery powered).

Qty 3 subsystems were defined:

  1. The rotating persistence of vision system. The rotating POV was selected to be Arduino based as there were open source examples to start the build with. It is desired to have a centrifugal switch on the POV battery feed so it shuts off power when not spinning. The spin motor would be controlled by the second control system.

 

  1. The sound system and motor controls. This was selected to be an Arduino control. Why ? The only available sound players in my present inventory are WTV020 players, and altho they are old tech, I’ve used them several times, no learning curve.

The audio tracks were massaged by Audacity to Mono 16bit PCM .wav file, then processed to an AD4 format by AD4 converter SW, saved to a 1Gb micro SD card.

 

  1. The WW1 airplanes and dogfight controls. This was a tough one. Raspberry Pi Pico as selected to be the controller as it has 10X the clock speed of an Arduino and python PWM is easy and efficient to code.
    • Roll, pitch, and yaw servos on each airplane mounted on a rotating platform.
    • Each plane would have LED ring rotating meteor pattern on the front to look like a rotating propeller.
    • The base would need to be sturdy and heavy to stay in place during scene rotation. The platter rotation is planned to be edge driven by a pinch roller.
    • The dogfight action python code would be constructed frame by frame like a stop-action movie.

 

Build materials

Electrical:

Qty 2 Arduino Nanos

Raspberry Pi Pico

1 Gb SD for the WTV020

WTV020

Qty 4 LM2596 power supplies

GP2A25J0000F IR sensor

Qty 2  16LED NeoPixel rings

Qty 8 ultrabright green LEDs + qty 8 100 ohm resistors

LM386 audio amp module

TTP223 Capacitive touch switch

Qty 3 IRD540 MOSFET modules (homebrew)

Qty 3 power distribution boards (homebrew) 2 points in, multiple points out

12V 2A wall wart

Qty 2 3.7V 300 mAhr LiPo batteries

11.1V 3S 800mAhr LiPo battery

Misc. wires, terminal boards, solder

Qty 2 12 V motors

Small On-Off switches  

 

Mechanical:

Qty 2 4 inch inertia discs + shaft bullet connector (borrowed from the Arduino Engineering Kit)

Craftwood, balsa, craft paint for the airplanes

MDF base for the project 10 inches X 10 inches

2 feet 2X4

15 inch lazy susan bearing

White foamboard for Snoopy

Green foam sheets for the Christmas Tree  

Stainless steel backplate from a dryer drum + green spray paint

Hot glue gun

image

image

image

image

image

imageimage

/*
 * This Code  POV_XMASSNOOPY.ino
 * LED POV DISPLAY 
 * based on example code written by Palak Mehta on March 29,2019
  * 
 * connect leds on 2 to 9 digital pin of Nano
 * IR sensor out pin connect on 10 digital pin of Nano
 * 
 */
////////////////////////design a pattern of display the number and alphabates//////////////////////////////// 

int NUMBER9[]={1,1,1,1,0,0,0,1, 1,0,0,1,0,0,0,1, 1,0,0,1,0,0,0,1, 1,0,0,1,0,0,0,1, 1,1,1,1,1,1,1,1};
 int NUMBER8[]={0,1,1,0,1,1,1,0, 1,0,0,1,0,0,0,1, 1,0,0,1,0,0,0,1, 1,0,0,1,0,0,0,1, 0,1,1,0,1,1,1,0};
 int NUMBER7[]={1,0,0,0,0,0,0,0, 1,0,0,0,1,0,0,0, 1,0,0,0,1,0,0,0, 1,0,0,1,1,1,1,1, 1,1,1,0,1,0,0,0};
 int NUMBER6[]={1,1,1,1,1,1,1,1, 1,0,0,0,1,0,0,1, 1,0,0,0,1,0,0,1, 1,0,0,0,1,0,0,1, 1,0,0,0,1,1,1,1};
 int NUMBER5[]={1,1,1,1,1,0,0,1, 1,0,0,0,1,0,0,1, 1,0,0,0,1,0,0,1, 1,0,0,0,1,0,0,1, 1,0,0,0,1,1,1,1};
 int NUMBER2[]= {1,0,0,0,0,0,1,1, 1,0,0,0,0,1,0,1, 1,0,0,0,1,0,0,1, 1,0,0,1,0,0,0,1, 0,1,1,0,0,0,0,1};
 int NUMBER1[]= {0,0,1,0,0,0,0,0, 0,1,0,0,0,0,0,0, 1,1,1,1,1,1,1,1, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0};
 int NUMBER0[]= {1,1,1,1,1,1,1,1, 1,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,1, 1,1,1,1,1,1,1,1};

 int _[] = {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0};
 int A[] = {1,1,1,1,1,1,1,1, 1,0,0,1,0,0,0,0, 1,0,0,1,0,0,0,0, 1,0,0,1,0,0,0,0, 1,1,1,1,1,1,1,1};
 int B[] = {1,1,1,1,1,1,1,1, 1,0,0,1,0,0,0,1, 1,0,0,1,0,0,0,1, 1,0,0,1,0,0,0,1, 0,1,1,0,1,1,1,0};
 int C[] = {0,0,1,1,1,1,0,0, 0,1,0,0,0,0,1,0, 1,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,1};
 int D[] = {1,1,1,1,1,1,1,1, 1,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,1, 0,1,0,0,0,0,1,0, 0,0,1,1,1,1,0,0};
 int E[] = {1,1,1,1,1,1,1,1, 1,0,0,1,0,0,0,1, 1,0,0,1,0,0,0,1, 1,0,0,1,0,0,0,1, 1,0,0,1,0,0,0,1};
 int F[] = {1,1,1,1,1,1,1,1, 1,0,0,1,0,0,0,0, 1,0,0,1,0,0,0,0, 1,0,0,1,0,0,0,0, 1,0,0,1,0,0,0,0};
 int G[] = {0,1,1,1,1,1,1,1, 1,0,0,0,0,0,0,1, 1,0,0,0,1,0,0,1, 1,0,0,0,1,0,0,1, 1,0,0,0,1,1,1,0};
 int H[] = {1,1,1,1,1,1,1,1, 0,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0, 1,1,1,1,1,1,1,1};
 int I[] = {1,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,1, 1,1,1,1,1,1,1,1, 1,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,1};
 int J[] = {0,0,0,0,0,1,1,0, 0,0,0,0,1,0,0,1, 0,0,0,0,0,0,0,1, 0,0,0,0,0,0,0,1, 1,1,1,1,1,1,1,0};
 int K[] = {1,1,1,1,1,1,1,1, 0,0,0,1,1,0,0,0, 0,0,1,0,0,1,0,0, 0,1,0,0,0,0,1,0, 1,0,0,0,0,0,0,1};
 int L[] = {1,1,1,1,1,1,1,1, 0,0,0,0,0,0,0,1, 0,0,0,0,0,0,0,1, 0,0,0,0,0,0,0,1, 0,0,0,0,0,0,0,1};
 int M[] = {1,1,1,1,1,1,1,1, 0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0, 0,1,0,0,0,0,0,0, 1,1,1,1,1,1,1,1};
 int N[] = {1,1,1,1,1,1,1,1, 0,0,1,0,0,0,0,0, 0,0,0,1,1,0,0,0, 0,0,0,0,0,1,0,0, 1,1,1,1,1,1,1,1};
 int O[] = {0,1,1,1,1,1,1,0, 1,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,1, 0,1,1,1,1,1,1,0};
 int P[] = {1,1,1,1,1,1,1,1, 1,0,0,1,0,0,0,0, 1,0,0,1,0,0,0,0, 1,0,0,1,0,0,0,0, 0,1,1,0,0,0,0,0};
 int Q[] = {0,1,1,1,1,1,1,0, 1,0,0,0,0,0,0,1, 1,0,0,0,0,1,0,1, 0,1,1,1,1,1,1,0, 0,0,0,0,0,0,0,1};
 int R[] = {1,1,1,1,1,1,1,1, 1,0,0,1,1,0,0,0, 1,0,0,1,0,1,0,0, 1,0,0,1,0,0,1,0, 0,1,1,0,0,0,0,1};
 int S[] = {0,1,1,1,0,0,0,1, 1,0,0,0,1,0,0,1, 1,0,0,0,1,0,0,1, 1,0,0,0,1,0,0,1, 1,0,0,0,1,1,1,0};
 int T[] = {1,0,0,0,0,0,0,0, 1,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1, 1,0,0,0,0,0,0,0, 1,0,0,0,0,0,0,0};
 int U[] = {1,1,1,1,1,1,1,0, 0,0,0,0,0,0,0,1, 0,0,0,0,0,0,0,1, 0,0,0,0,0,0,0,1, 1,1,1,1,1,1,1,0};
 int V[] = {1,1,1,1,1,1,0,0, 0,0,0,0,0,0,1,0, 0,0,0,0,0,0,0,1, 0,0,0,0,0,0,1,0, 1,1,1,1,1,1,0,0};
 int W[] = {1,1,1,1,1,1,1,1, 0,0,0,0,0,0,1,0, 0,0,0,0,0,1,0,0, 0,0,0,0,0,0,1,0, 1,1,1,1,1,1,1,1};
 int X[] = {1,1,0,0,0,0,1,1, 0,0,1,0,0,1,0,0, 0,0,0,1,1,0,0,0, 0,0,1,0,0,1,0,0, 1,1,0,0,0,0,1,1};
 int Y[] = {1,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0, 0,0,0,1,1,1,1,1, 0,0,1,0,0,0,0,0, 1,1,0,0,0,0,0,0};
 int Z[] = {1,0,0,0,0,1,1,1, 1,0,0,0,1,0,0,1, 1,0,0,1,0,0,0,1, 1,0,1,0,0,0,0,1, 1,1,0,0,0,0,0,1};
 
 int* alpha[]= {A,B,C,D,E,F,G,H,I,J,K,L,M,N};//,T,U,V,W,X,Y,Z};
 int letterSpace;
 int delayTime;
int RPMcount=0;
int HomeSwitch=HIGH;

 #define IR_pin 10
 
 void setup()
 { 
    //    Serial.begin(115200);       
         pinMode(IR_pin,INPUT);
         for( int i = 2; i<10 ;i++ ) // setting the ports of the leds to OUTPUT
           {
            pinMode(i, OUTPUT);
           }
                
         letterSpace =1;// defining the space between the letters (ms)         
         delayTime =1;// defining the time dots appear (ms)
}


 void printLetter(int letter[])
 {
           int y;
          // printing the first y row of the letter
           for (y=0; y<8; y++)
           {
           digitalWrite(y+2, letter[y]);
           }
           delay(delayTime);
          // printing the second y row of the letter
           for (y=0; y<8; y++)
           {
           digitalWrite(y+2, letter[y+8]);
           }
           delay(delayTime);
          // printing the third y row of the letter
           for (y=0; y<8; y++)
           {
           digitalWrite(y+2, letter[y+16]);
           }
           delay(delayTime);
           for(y = 0; y<8; y++) {
           digitalWrite(y+2, letter[y+24]);
           }
           delay(delayTime);
          for(y = 0; y<8; y++) {
           digitalWrite(y+2, letter[y+32]);
           }
           delay(delayTime);
           // printing the space between the letters
           for (y=0; y<8; y++)
           {
           digitalWrite(y+2, 0);
           }
           delay(letterSpace);
 }

 
 void loop()
 {
  HomeSwitch=digitalRead(IR_pin);
//  if(digitalRead(IR_pin)==LOW)
  if(HomeSwitch==LOW)
    { (RPMcount=RPMcount+1);
    if (RPMcount>1500) 
    {RPMcount=0;}
//Serial.print("RPMcount = ");
//  Serial.println(RPMcount);    
  }
  
//  if((digitalRead(IR_pin)==LOW)&&(RPMcount<1000))
    if((HomeSwitch==LOW)&&(RPMcount<300))
  {
     printLetter (M);
     printLetter (E);
     printLetter (R);
     printLetter (R);
     printLetter (Y);
     printLetter (_);
     printLetter (_);
     printLetter (X);
     printLetter (M);
     printLetter (A);
     printLetter (S);
     printLetter (_);
     printLetter (_);
   }

 if((HomeSwitch==LOW)&&(RPMcount>299)&&(RPMcount<600))
// if((digitalRead(IR_pin)==LOW)&&(RPMcount>300)&&(RPMcount<601))
  {
     printLetter (F);
     printLetter (R);
     printLetter (O);
     printLetter (M);
     printLetter (_);
     printLetter (S);
     printLetter (N);
     printLetter (O);
     printLetter (O);
     printLetter (P);
     printLetter (Y);
     printLetter (_);
     printLetter (_);
 
  }

if((HomeSwitch==LOW)&&(RPMcount>600)&&(RPMcount<900))
// if((digitalRead(IR_pin)==LOW)&&(RPMcount>1999)&&(RPMcount<2999))
  {
     printLetter (A);
     printLetter (N);
     printLetter (D);
     printLetter (_);
     printLetter (R);
     printLetter (E);
     printLetter (D);
     printLetter (_);
     printLetter (B);
     printLetter (A);
     printLetter (R);
     printLetter (O);
     printLetter (N);
 
  }

if((HomeSwitch==LOW)&&(RPMcount>900)&&(RPMcount<1200))
  {
     printLetter (H);
     printLetter (A);
     printLetter (P);
     printLetter (P);
     printLetter (Y);
     printLetter (_);
     printLetter (N);
     printLetter (E);
     printLetter (W);
     printLetter (_);
     printLetter (Y);
     printLetter (E);
     printLetter (A);
     printLetter (R);
    }

}

 

// SnoopyAudio_POVmotorcontrol.ino
// started from GasMaskMatrixEyesAndSoundWorks.ino
//
//
// D2=D5 for WTV020 control interface
//  D6 is capactitive switch PB input for run/stop  TTP223  
//  D7 is output for POV motor run 

//#include "LedControl.h"

//LedControl lc=LedControl(12,10,11,2);  // Pins: DIN,CLK,CS, # of Display connected

#include <Wtv020sd16p.h>

int resetPin = 2;  // The pin number of the reset pin.
int clockPin = 3;  // The pin number of the clock pin.
int dataPin = 4;  // The pin number of the data pin.
int busyPin = 5;  // The pin number of the busy pin.
Wtv020sd16p wtv020sd16p(resetPin,clockPin,dataPin,busyPin);

//unsigned long delayTime=200;  // Delay between Frames

// Put values in arrays

int RUNPB=LOW;
int RUN=LOW;
int BUSY=LOW;
int RUNlastScan=LOW;
int trackNumber=0;

void setup()
{
pinMode(6,INPUT);  
pinMode(7,OUTPUT);
pinMode(13,OUTPUT); //for diagnostic display only
  

  //Initializes the WTV020 module.
  wtv020sd16p.reset();

  delay(1000);
//  Serial.begin(9600);
}


void loop()
{
    RUNPB=digitalRead(6); //toggle run bit 
//      Serial.print("runpb=");
//      Serial.println(RUNPB);

  
  if (RUNPB==HIGH)    // while run is high, spin POV motor
    {
      digitalWrite(7,HIGH); //enables POV motor power supply
      digitalWrite(13,HIGH);//for show
        delay (20);
    BUSY=digitalRead(5);
    trackNumber=0;
    if ((BUSY==LOW)&&(trackNumber==0))
      { wtv020sd16p.playVoice(0);
        delay(184800);   // better to have a while loop looking for BUSY signal to go to HIGH
        trackNumber=1;
        }
    if ((BUSY==LOW)&&(trackNumber==1))
      { wtv020sd16p.playVoice(1);
        delay(146400);
        trackNumber=2;
        }
    if ((BUSY==LOW)&&(trackNumber==2))
      { wtv020sd16p.playVoice(2);
        delay(30000);
        trackNumber=3;
        }
    if ((BUSY==LOW)&&(trackNumber==3))
      { wtv020sd16p.playVoice(3);
        delay(34200);
        trackNumber=0;
        }
    
    }
    else
      {digitalWrite(7,LOW);
      digitalWrite(13,LOW);
       wtv020sd16p.stopVoice();
      }
    
}

# RedBaronSopwithCamel.py
# started from SqawkinOnMyCoffinWorks.py  

from machine import Pin, I2C, PWM
#from ssd1306 import SSD1306_I2C
#import framebuf
import math
import utime
import random

RedBaronRoll = PWM(Pin(19))# physical pin25
RedBaronPitch = PWM(Pin(18))# physical pin24
SopwithCamelRoll = PWM(Pin(17))# physical pin22
SopwithCamelPitch = PWM(Pin(16))# physical pin21

RedBaronRoll.freq(50) # 2 Hz is 20 msec period
RedBaronPitch.freq(50) # 2 Hz is 20 msec period
SopwithCamelRoll.freq(50) # 2 Hz is 20 msec period
SopwithCamelPitch.freq(50) # 2 Hz is 20 msec period
# 100% duty of PWM is 65535 counts
# 2 ms of 20 ms is 10% for full spd FWD 6553
# ( 1.5 ms / 20 ms ) * 65535 = 4875 for zero degrees
# 1 ms of 20 ms is full neg  3251 counts
RedBaronRoll.duty_u16(4875) # 2 Hz is 20 msec period
RedBaronPitch.duty_u16(4875) # 2 Hz is 20 msec period
SopwithCamelRoll.duty_u16(4875)# 2 Hz is 20 msec period
SopwithCamelPitch.duty_u16(4875) # 2 Hz is 20 msec period

# 100% duty of PWM is 65535 counts
# 2 ms of 20 ms is 10% for full spd FWD 6553
# ( 1.5 ms / 20 ms ) * 65535 = 4875 for zero degrees
# 1 ms of 20 ms is full neg  3251 counts

from neopixel import Neopixel

numpix = 32
pixels = Neopixel(numpix, 1, 22, "GRB") #arameters number of LEDs, state machine ID, GPIO number and mode (RGB or RGBW) in that order. 
# strip = Neopixel(numpix, 0, 0, "GRBW")
#colors taking values between 0 and 255.
#red = (255, 0, 0)
#orange = (255, 50, 0)
#yellow = (255, 100, 0)
#green = (0, 255, 0)
#blue = (0, 0, 255)
#indigo = (100, 0, 90)
#violet = (200, 0, 100)
#colors_rgb = [red, orange, yellow, green, blue, indigo, violet]
#GPIO22 is pin29

#pixels.set_pixel(1, (0, 0, 0))
#pixels.set_pixel(0, (0, 0, 0))
#pixels.show()





def ClearNeoPixels():
    for x in range(32):
        pixels.set_pixel(x, (0, 0, 0))
    pixels.show()

def PropRedMeteorPos0():
 # pixel 0,8,15,24 are dim
 # pixel 0,8,15,24 are brighter
 # pixel 0,8,15,24 are a step brighter
 # pixel 0,8,15,24 are brightest
 # set all pixels to dark
     ClearNeoPixels()
     pixels.set_pixel(0, (3, 0, 0))
     pixels.set_pixel(1, (6, 0, 0))    
     pixels.set_pixel(2, (15, 0, 0))
     pixels.set_pixel(3, (60, 0, 0))
     pixels.set_pixel(8, (3, 0, 0))
     pixels.set_pixel(9, (6, 0, 0))    
     pixels.set_pixel(10, (15, 0, 0))
     pixels.set_pixel(11, (60, 0, 0))
     pixels.show()
     
def PropRedMeteorPos1():
 # pixel 0,8,15,24 are dim
 # pixel 0,8,15,24 are brighter
 # pixel 0,8,15,24 are a step brighter
 # pixel 0,8,15,24 are brightest
 # set all pixels to dark
     ClearNeoPixels()
     pixels.set_pixel(1, (3, 0, 0))
     pixels.set_pixel(2, (6, 0, 0))    
     pixels.set_pixel(3, (15, 0, 0))
     pixels.set_pixel(4, (60, 0, 0))
     pixels.set_pixel(9, (3, 0, 0))
     pixels.set_pixel(10, (6, 0, 0))    
     pixels.set_pixel(11, (15, 0, 0))
     pixels.set_pixel(12, (60, 0, 0))     
     pixels.show()

def PropRedMeteorPos2():
 # pixel 0,8,15,24 are dim
 # pixel 0,8,15,24 are brighter
 # pixel 0,8,15,24 are a step brighter
 # pixel 0,8,15,24 are brightest
 # set all pixels to dark
     ClearNeoPixels()
     pixels.set_pixel(2, (3, 0, 0))
     pixels.set_pixel(3, (6, 0, 0))    
     pixels.set_pixel(4, (15, 0, 0))
     pixels.set_pixel(5, (60, 0, 0))
     pixels.set_pixel(10, (3, 0, 0))
     pixels.set_pixel(11, (6, 0, 0))    
     pixels.set_pixel(12, (15, 0, 0))
     pixels.set_pixel(13, (60, 0, 0))     
     pixels.show()
     
def PropRedMeteorPos3():
 # pixel 0,8,15,24 are dim
 # pixel 0,8,15,24 are brighter
 # pixel 0,8,15,24 are a step brighter
 # pixel 0,8,15,24 are brightest
 # set all pixels to dark
     ClearNeoPixels()
     pixels.set_pixel(3, (3, 0, 0))
     pixels.set_pixel(4, (6, 0, 0))    
     pixels.set_pixel(5, (15, 0, 0))
     pixels.set_pixel(6, (60, 0, 0))
     pixels.set_pixel(11, (3, 0, 0))
     pixels.set_pixel(12, (6, 0, 0))    
     pixels.set_pixel(13, (15, 0, 0))
     pixels.set_pixel(14, (60, 0, 0))     
     pixels.show()
     
def PropRedMeteorPos4():
 # pixel 0,8,15,24 are dim
 # pixel 0,8,15,24 are brighter
 # pixel 0,8,15,24 are a step brighter
 # pixel 0,8,15,24 are brightest
 # set all pixels to dark
     ClearNeoPixels()
     pixels.set_pixel(4, (3, 0, 0))
     pixels.set_pixel(5, (6, 0, 0))    
     pixels.set_pixel(6, (15, 0, 0))
     pixels.set_pixel(7, (60, 0, 0))
     pixels.set_pixel(12, (3, 0, 0))
     pixels.set_pixel(13, (6, 0, 0))    
     pixels.set_pixel(14, (15, 0, 0))
     pixels.set_pixel(15, (60, 0, 0))     
     pixels.show()     

def PropRedMeteorPos5():
 # pixel 0,8,15,24 are dim
 # pixel 0,8,15,24 are brighter
 # pixel 0,8,15,24 are a step brighter
 # pixel 0,8,15,24 are brightest
 # set all pixels to dark
     ClearNeoPixels()
     pixels.set_pixel(5, (3, 0, 0))
     pixels.set_pixel(6, (6, 0, 0))    
     pixels.set_pixel(7, (15, 0, 0))
     pixels.set_pixel(8, (60, 0, 0))
     pixels.set_pixel(13, (3, 0, 0))
     pixels.set_pixel(14, (6, 0, 0))    
     pixels.set_pixel(15, (15, 0, 0))
     pixels.set_pixel(0, (60, 0, 0))     
     pixels.show()    

def PropRedMeteorPos6():
 # pixel 0,8,15,24 are dim
 # pixel 0,8,15,24 are brighter
 # pixel 0,8,15,24 are a step brighter
 # pixel 0,8,15,24 are brightest
 # set all pixels to dark
     ClearNeoPixels()
     pixels.set_pixel(6, (3, 0, 0))
     pixels.set_pixel(7, (6, 0, 0))    
     pixels.set_pixel(8, (15,0, 0))
     pixels.set_pixel(9, (60, 0, 0))
     pixels.set_pixel(14, (3, 0, 0))
     pixels.set_pixel(15, (6, 0, 0))    
     pixels.set_pixel(0, (15, 0, 0))
     pixels.set_pixel(1, (60, 0, 0))     
     pixels.show()

def PropRedMeteorPos7():
 # pixel 0,8,15,24 are dim
 # pixel 0,8,15,24 are brighter
 # pixel 0,8,15,24 are a step brighter
 # pixel 0,8,15,24 are brightest
 # set all pixels to dark
     ClearNeoPixels()
     pixels.set_pixel(7, (3, 0, 0))
     pixels.set_pixel(8, (6, 0, 0))    
     pixels.set_pixel(9, (15, 0, 0))
     pixels.set_pixel(14, (60, 0, 0))
     pixels.set_pixel(15, (3, 0, 0))
     pixels.set_pixel(0, (5, 0, 0))    
     pixels.set_pixel(1, (15, 0, 0))
     pixels.set_pixel(2, (60, 0, 0))
 #    pixels.set_pixel(2, (60, 0, 0)) `    
     pixels.show() 
 #pixels.set_pixel(0, (50, 0, 0))
     
def PropYELLOWMeteorPos0():
 # pixel 0,8,15,24 are dim
 # pixel 0,8,15,24 are brighter
 # pixel 0,8,15,24 are a step brighter
 # pixel 0,8,15,24 are brightest
 # set all pixels to dark
     ClearNeoPixels()
     pixels.set_pixel(16, (3, 3, 0))
     pixels.set_pixel(17, (6, 6, 0))    
     pixels.set_pixel(18, (15, 15, 0))
     pixels.set_pixel(19, (60, 60, 0))
     pixels.set_pixel(24, (3, 3, 0))
     pixels.set_pixel(25, (6, 6, 0))    
     pixels.set_pixel(26, (15, 15, 0))
     pixels.set_pixel(27, (60, 60, 0))
     pixels.show()
     
def PropYELLOWMeteorPos1():
 # pixel 0,8,15,24 are dim
 # pixel 0,8,15,24 are brighter
 # pixel 0,8,15,24 are a step brighter
 # pixel 0,8,15,24 are brightest
 # set all pixels to dark
     ClearNeoPixels()
     pixels.set_pixel(17, (3, 3, 0))
     pixels.set_pixel(18, (6, 6, 0))    
     pixels.set_pixel(19, (15, 15, 0))
     pixels.set_pixel(20, (60, 60, 0))
     pixels.set_pixel(25, (3, 3, 0))
     pixels.set_pixel(26, (6, 6, 0))    
     pixels.set_pixel(27, (15, 15, 0))
     pixels.set_pixel(28, (60, 60, 0))
     pixels.show()

def PropYELLOWMeteorPos2():
 # pixel 0,8,15,24 are dim
 # pixel 0,8,15,24 are brighter
 # pixel 0,8,15,24 are a step brighter
 # pixel 0,8,15,24 are brightest
 # set all pixels to dark
     ClearNeoPixels()
     pixels.set_pixel(18, (3, 3, 0))
     pixels.set_pixel(19, (6, 6, 0))    
     pixels.set_pixel(20, (15, 15, 0))
     pixels.set_pixel(21, (60, 60, 0))
     pixels.set_pixel(26, (3, 3, 0))
     pixels.set_pixel(27, (6, 6, 0))    
     pixels.set_pixel(28, (15, 15, 0))
     pixels.set_pixel(29, (60, 60, 0))
     pixels.show()
     
def PropYELLOWMeteorPos3():
 # pixel 0,8,15,24 are dim
 # pixel 0,8,15,24 are brighter
 # pixel 0,8,15,24 are a step brighter
 # pixel 0,8,15,24 are brightest
 # set all pixels to dark
     ClearNeoPixels()
     pixels.set_pixel(19, (3, 3, 0))
     pixels.set_pixel(20, (6, 6, 0))    
     pixels.set_pixel(21, (15, 15, 0))
     pixels.set_pixel(22, (60, 60, 0))
     pixels.set_pixel(27, (3, 3, 0))
     pixels.set_pixel(28, (6, 6, 0))    
     pixels.set_pixel(29, (15, 15, 0))
     pixels.set_pixel(30, (60, 60, 0))
     pixels.show()
     
def PropYELLOWMeteorPos4():
 # pixel 0,8,15,24 are dim
 # pixel 0,8,15,24 are brighter
 # pixel 0,8,15,24 are a step brighter
 # pixel 0,8,15,24 are brightest
 # set all pixels to dark
     ClearNeoPixels()
     pixels.set_pixel(20, (3, 3, 0))
     pixels.set_pixel(21, (6, 6, 0))    
     pixels.set_pixel(22, (15, 15, 0))
     pixels.set_pixel(23, (60, 60, 0))
     pixels.set_pixel(28, (3, 3, 0))
     pixels.set_pixel(29, (6, 6, 0))    
     pixels.set_pixel(30, (15, 15, 0))
     pixels.set_pixel(31, (60, 60, 0))
     pixels.show()    

def PropYELLOWMeteorPos5():
 # pixel 0,8,15,24 are dim
 # pixel 0,8,15,24 are brighter
 # pixel 0,8,15,24 are a step brighter
 # pixel 0,8,15,24 are brightest
 # set all pixels to dark
     ClearNeoPixels()
     pixels.set_pixel(21, (3, 3, 0))
     pixels.set_pixel(22, (6, 6, 0))    
     pixels.set_pixel(23, (15, 15, 0))
     pixels.set_pixel(24, (60, 60, 0))
     pixels.set_pixel(29, (3, 3, 0))
     pixels.set_pixel(30, (6, 6, 0))    
     pixels.set_pixel(31, (15, 15, 0))
     pixels.set_pixel(16, (60, 60, 0))
     pixels.show()     

def PropYELLOWMeteorPos6():
 # pixel 0,8,15,24 are dim
 # pixel 0,8,15,24 are brighter
 # pixel 0,8,15,24 are a step brighter
 # pixel 0,8,15,24 are brightest
 # set all pixels to dark
     ClearNeoPixels()
     pixels.set_pixel(22, (3, 3, 0))
     pixels.set_pixel(23, (6, 6, 0))    
     pixels.set_pixel(24, (20, 20, 0))
     pixels.set_pixel(25, (60, 60, 0))
     pixels.set_pixel(30, (3, 3, 0))
     pixels.set_pixel(31, (6, 6, 0))    
     pixels.set_pixel(16, (15, 15, 0))
     pixels.set_pixel(17, (60, 60, 0))
     pixels.show() 

def PropYELLOWMeteorPos7():
 # pixel 0,8,15,24 are dim
 # pixel 0,8,15,24 are brighter
 # pixel 0,8,15,24 are a step brighter
 # pixel 0,8,15,24 are brightest
 # set all pixels to dark
     ClearNeoPixels()
     pixels.set_pixel(23, (3, 3, 0))
     pixels.set_pixel(24, (6, 6, 0))    
     pixels.set_pixel(25, (20, 20, 0))
     pixels.set_pixel(26, (60, 60, 0))
     pixels.set_pixel(31, (3, 3, 0))
     pixels.set_pixel(16, (6, 6, 0))    
     pixels.set_pixel(17, (15, 15, 0))
     pixels.set_pixel(18, (60, 60, 0))
     pixels.show() 
 
 
################# DEMO TESTING SERVOS ######

#RavenLeftWingServo.duty_u16(4875)
#utime.sleep(.2)


########################## the program ############################
#rotating meteor on props
#
#
loopcounts=0
while True:
    # propeller WS2812 LEDs meteor routine
    PropRedMeteorPos0()
    PropYELLOWMeteorPos0()
    utime.sleep(.01)
    PropRedMeteorPos1()
    PropYELLOWMeteorPos1()
    utime.sleep(.01)
    PropRedMeteorPos2()
    PropYELLOWMeteorPos2()
    utime.sleep(.01)
    PropRedMeteorPos3()
    PropYELLOWMeteorPos3()
    utime.sleep(.01)
    PropRedMeteorPos4()
    PropYELLOWMeteorPos4()
    utime.sleep(.01)
    PropRedMeteorPos5()
    PropYELLOWMeteorPos5()
    utime.sleep(.01)
    PropRedMeteorPos6()
    PropYELLOWMeteorPos6()
    utime.sleep(.01)
    PropRedMeteorPos7()
    PropYELLOWMeteorPos7()
    utime.sleep(.01)
    loopcounts=loopcounts+1  # a loop count is ~ 90- 100 ms
    
    
    # dogfight servos start with everything flat zero degrees
    # The code steps are written this way like frames of a stop action movie
    if loopcounts==1:
        RedBaronRoll.duty_u16(4875)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        #RedBaronPitch.duty_u16(4875) # #4875 is 0, -90 = 3251  +90 6553  Pin24 GPIO18
        SopwithCamelRoll.duty_u16(4875)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
        SopwithCamelPitch.duty_u16(4875) ##4875 is 0, -90 = 3251  +90 6553  Pin21 GPIO16 
     
    if loopcounts==21:
        RedBaronRoll.duty_u16(4900)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
    if loopcounts==22:
        RedBaronRoll.duty_u16(4800)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
    if loopcounts==23:
        RedBaronRoll.duty_u16(4700)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
    if loopcounts==24:
        RedBaronRoll.duty_u16(4600)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
    if loopcounts==25:
        RedBaronRoll.duty_u16(4500)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
    if loopcounts==26:
        RedBaronRoll.duty_u16(4400)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(4900)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
        SopwithCamelPitch.duty_u16(4900) ##4875 is 0, -90 = 3251  +90 6553  Pin21 GPIO16 
    if loopcounts==27:
        RedBaronRoll.duty_u16(4300)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(4700)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
        SopwithCamelPitch.duty_u16(4700) ##4875 is 0, -90 = 3251  +90 6553  Pin21 GPIO16         
    if loopcounts==28:
        RedBaronRoll.duty_u16(4300)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(4600)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
        SopwithCamelPitch.duty_u16(4600) ##4875 is 0, -90 = 3251  +90 6553  Pin21 GPIO16
    if loopcounts==29:
        RedBaronRoll.duty_u16(4300)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(4500)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
        SopwithCamelPitch.duty_u16(4500) ##4875 is 0, -90 = 3251  +90 6553  Pin21 GPIO16
    if loopcounts==30:
        RedBaronRoll.duty_u16(4200)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(4600)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
        SopwithCamelPitch.duty_u16(4600) ##4875 is 0, -90 = 3251  +90 6553  Pin21 GPIO16
    if loopcounts==31:
        RedBaronRoll.duty_u16(4000)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(4500)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
        SopwithCamelPitch.duty_u16(4500) ##4875 is 0, -90 = 3251  +90 6553  Pin21 GPIO16        
    if loopcounts==32:
        RedBaronRoll.duty_u16(3900)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(4400)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
        SopwithCamelPitch.duty_u16(4400) ##4875 is 0, -90 = 3251  +90 6553  Pin21 GPIO16         
    if loopcounts==33:
        RedBaronRoll.duty_u16(3800)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(4500)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
        SopwithCamelPitch.duty_u16(4500) ##4875 is 0, -90 = 3251  +90 6553  Pin21 GPIO16         
    if loopcounts==34:
        RedBaronRoll.duty_u16(3700)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(4400)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
        SopwithCamelPitch.duty_u16(4400) ##4875 is 0, -90 = 3251  +90 6553  Pin21 GPIO16         
    if loopcounts==35:
        RedBaronRoll.duty_u16(3600)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(4300)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
        SopwithCamelPitch.duty_u16(4300) ##4875 is 0, -90 = 3251  +90 6553  Pin21 GPIO16         
    if loopcounts==36:
        RedBaronRoll.duty_u16(3500)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(4200)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
        SopwithCamelPitch.duty_u16(4200) ##4875 is 0, -90 = 3251  +90 6553  Pin21 GPIO16
    if loopcounts==37:
        RedBaronRoll.duty_u16(3400)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(4100)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
        SopwithCamelPitch.duty_u16(4100) ##4875 is 0, -90 = 3251  +90 6553  Pin21 GPIO16
    if loopcounts==38:
        #RedBaronRoll.duty_u16(3400)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(4000)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
        SopwithCamelPitch.duty_u16(4000) ##4875 is 0, -90 = 3251  +90 6553  Pin21 GPIO16
    if loopcounts==39:
        RedBaronRoll.duty_u16(3500)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(3900)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
        SopwithCamelPitch.duty_u16(3900) ##4875 is 0, -90 = 3251  +90 6553  Pin21 GPIO16
    if loopcounts==40:
        RedBaronRoll.duty_u16(3700)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(3800)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
        SopwithCamelPitch.duty_u16(3800) ##4875 is 0, -90 = 3251  +90 6553  Pin21 GPIO16
    if loopcounts==41:
        RedBaronRoll.duty_u16(3900)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(3700)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
        SopwithCamelPitch.duty_u16(3700) ##4875 is 0, -90 = 3251  +90 6553  Pin21 GPIO16         
    if loopcounts==42:
        RedBaronRoll.duty_u16(4100)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(3600)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
        SopwithCamelPitch.duty_u16(3600) ##4875 is 0, -90 = 3251  +90 6553  Pin21 GPIO16         
    if loopcounts==43:
        RedBaronRoll.duty_u16(4400)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(3500)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
        SopwithCamelPitch.duty_u16(3500) ##4875 is 0, -90 = 3251  +90 6553  Pin21 GPIO16           
    if loopcounts==44:
        RedBaronRoll.duty_u16(4900)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(3900)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
        SopwithCamelPitch.duty_u16(3900) ##4875 is 0, -90 = 3251  +90 6553  Pin21 GPIO16           
    if loopcounts==45:
        RedBaronRoll.duty_u16(5100)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(4100)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
        SopwithCamelPitch.duty_u16(4100) ##4875 is 0, -90 = 3251  +90 6553  Pin21 GPIO16
    if loopcounts==46:
        RedBaronRoll.duty_u16(5300)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(4300)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
        SopwithCamelPitch.duty_u16(4300) ##4875 is 0, -90 = 3251  +90 6553  Pin21 GPIO16
    if loopcounts==47:
        RedBaronRoll.duty_u16(5500)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(4500)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
        SopwithCamelPitch.duty_u16(4500) ##4875 is 0, -90 = 3251  +90 6553  Pin21 GPIO16
    if loopcounts==48:
        RedBaronRoll.duty_u16(5700)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(4700)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
        SopwithCamelPitch.duty_u16(4700) ##4875 is 0, -90 = 3251  +90 6553  Pin21 GPIO16
    if loopcounts==49:
        RedBaronRoll.duty_u16(5900)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(4900)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
        SopwithCamelPitch.duty_u16(4900) ##4875 is 0, -90 = 3251  +90 6553  Pin21 GPIO16
    if loopcounts==50:
        RedBaronRoll.duty_u16(6100)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(5100)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
        SopwithCamelPitch.duty_u16(5100) ##4875 is 0, -90 = 3251  +90 6553  Pin21 GPIO16
    if loopcounts==51:
        RedBaronRoll.duty_u16(6300)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(5300)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
        SopwithCamelPitch.duty_u16(5300) ##4875 is 0, -90 = 3251  +90 6553  Pin21 GPIO16
    if loopcounts==52:
        RedBaronRoll.duty_u16(6400)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(5500)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
        SopwithCamelPitch.duty_u16(5500) ##4875 is 0, -90 = 3251  +90 6553  Pin21 GPIO16
    if loopcounts==53:
        #RedBaronRoll.duty_u16(3400)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(5700)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
        SopwithCamelPitch.duty_u16(5700) ##4875 is 0, -90 = 3251  +90 6553  Pin21 GPIO16
    if loopcounts==54:
        #RedBaronRoll.duty_u16(3400)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(5900)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
        SopwithCamelPitch.duty_u16(5900) ##4875 is 0, -90 = 3251  +90 6553  Pin21 GPIO16
    if loopcounts==55:
        #RedBaronRoll.duty_u16(3400)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(6100)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
        SopwithCamelPitch.duty_u16(6100) ##4875 is 0, -90 = 3251  +90 6553  Pin21 GPIO16
    if loopcounts==57:
        RedBaronRoll.duty_u16(6000)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(5900)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
        SopwithCamelPitch.duty_u16(5900) ##4875 is 0, -90 = 3251  +90 6553  Pin21 GPIO16
    if loopcounts==59:
        RedBaronRoll.duty_u16(5800)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(5900)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
        SopwithCamelPitch.duty_u16(5700) ##4875 is 0, -90 = 3251  +90 6553  Pin21 GPIO16
    if loopcounts==61:
        RedBaronRoll.duty_u16(5600)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(5700)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
        SopwithCamelPitch.duty_u16(5500) ##4875 is 0, -90 = 3251  +90 6553  Pin21 GPIO16
    if loopcounts==62:
        RedBaronRoll.duty_u16(5400)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(5500)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
        SopwithCamelPitch.duty_u16(5300) ##4875 is 0, -90 = 3251  +90 6553  Pin21 GPIO16
    if loopcounts==63:
        RedBaronRoll.duty_u16(5200)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(5400)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
        SopwithCamelPitch.duty_u16(5200) ##4875 is 0, -90 = 3251  +90 6553  Pin21 GPIO16
    if loopcounts==64:
        RedBaronRoll.duty_u16(5000)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(5200)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
        SopwithCamelPitch.duty_u16(5200) ##4875 is 0, -90 = 3251  +90 6553  Pin21 GPIO16
    if loopcounts==65:
        RedBaronRoll.duty_u16(5600)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(5100)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
        SopwithCamelPitch.duty_u16(5100) ##4875 is 0, -90 = 3251  +90 6553  Pin21 GPIO16
    if loopcounts==66:
        RedBaronRoll.duty_u16(5200)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(4900)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
        SopwithCamelPitch.duty_u16(4900) ##4875 is 0, -90 = 3251  +90 6553  Pin21 GPIO16
    if loopcounts==67:
        RedBaronRoll.duty_u16(4900)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(4900)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
        SopwithCamelPitch.duty_u16(4900) ##4875 is 0, -90 = 3251  +90 6553  Pin21 GPIO16
    if loopcounts==75:
        RedBaronRoll.duty_u16(5300)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(4900)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
        SopwithCamelPitch.duty_u16(4900) ##4875 is 0, -90 = 3251  +90 6553  Pin21 GPIO16
    if loopcounts==77:
        RedBaronRoll.duty_u16(5400)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(5000)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
        SopwithCamelPitch.duty_u16(5000) ##4875 is 0, -90 = 3251  +90 6553  Pin21 GPIO16
    if loopcounts==78:
        RedBaronRoll.duty_u16(5500)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(5100)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
        SopwithCamelPitch.duty_u16(5100) ##4875 is 0, -90 = 3251  +90 6553  Pin21 GPIO16
    if loopcounts==79:
        RedBaronRoll.duty_u16(5600)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(5200)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
        #SopwithCamelPitch.duty_u16(5000) ##4875 is 0, -90 = 3251  +90 6553  Pin21 GPIO16
    if loopcounts==80:
        RedBaronRoll.duty_u16(5700)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(5300)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
    if loopcounts==81:
        RedBaronRoll.duty_u16(4900)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(5400)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
    if loopcounts==82:
        RedBaronRoll.duty_u16(4900)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(5300)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
    if loopcounts==83:
        RedBaronRoll.duty_u16(4900)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(5200)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
    if loopcounts==84:
        RedBaronRoll.duty_u16(4900)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(5100)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
    if loopcounts==85:
        RedBaronRoll.duty_u16(4800)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(5100)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
    if loopcounts==86:
        RedBaronRoll.duty_u16(4600)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(4900)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
    if loopcounts==87:
        RedBaronRoll.duty_u16(4400)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(4800)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
    if loopcounts==88:
        RedBaronRoll.duty_u16(4200)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(4700)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
    if loopcounts==89:
        RedBaronRoll.duty_u16(3900)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(4600)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
    if loopcounts==89:
        RedBaronRoll.duty_u16(3700)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(4500)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
    if loopcounts==90:
        RedBaronRoll.duty_u16(3700)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(4400)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
    if loopcounts==91:
        RedBaronRoll.duty_u16(3700)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(4500)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
    if loopcounts==92:
        RedBaronRoll.duty_u16(3700)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(4600)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
    if loopcounts==93:
        RedBaronRoll.duty_u16(3800)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(4600)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
    if loopcounts==94:
        RedBaronRoll.duty_u16(4000)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(4700)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
    if loopcounts==95:
        RedBaronRoll.duty_u16(4100)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(4800)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
    if loopcounts==96:
        RedBaronRoll.duty_u16(4400)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(4900)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO17
    if loopcounts==97:
        RedBaronRoll.duty_u16(4700)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(4900)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO1
    if loopcounts==98:
        RedBaronRoll.duty_u16(4900)   #4875 is 0, -90 = 3251  +90 6553  Pin25 GPIO19
        SopwithCamelRoll.duty_u16(4900)  #4875 is 0, -90 = 3251  +90 6553  Pin22 GPIO1
    if loopcounts==100:
        loopcounts=0

Challenges & compromises:

A dryer air vane switch was used as a centrifugal switch on the POV rotor. Placement and rotor speed were critical as it was one of the heavier components at 9 grams, and needed to be by the edge of the flywheel to firmly close. At the final placement position for decent balance, its closings were intermittent at the final rotor speeds, so the centrifugal switch was bypassed. Its possible to replace the dryer switch with a tilt switch, and rebalance the POV rotor.

The airplanes were first concept was 3 axis: pitch, roll, & yaw motions, but the servo stack was too high and awkward. Yaw wouldn’t needed since the entire platter base was to rotate around the POV assembly. It was reduced to just pitch and yaw. The pitch and yaw servos worked fine individually during software development and testing. After the final assembly on the platter, the roll motions on both planes had some mechanical oscillation – resonance. If the roll motion as steadied with a touch, it dampened out and stopped, only to slowly restart a few seconds later.  This was decided to be a beneficial feature called turbulence. The power supplies were stiff, its possible the servos just need to be bigger.

The platter was designed to rotate around the POV display to have the Sopwith Camel chasing the Red Baron. During the build, it was discovered the 15 inch lazy susan bearing had a bind in one position. No matter how much exercising was done working graphite and Teflon powder into the bearings, the bind remained. The platter was thought to be edge driven motor roller, but the binding caused jamming and slipping. To have a working platter, a 9 to 10 inch gear with the center removed is needed to provide a belt drive for the platter. The project deadline nears, so the project had both planes face each other to do the dogfighting.

  • Sign in to reply

Top Comments

  • dougw
    dougw over 2 years ago +1
    Cute biplane and triplane..
  • robogary
    robogary over 2 years ago +1
    I also learned that 9g servos have a different output shaft radius and # of teeth depending on the vendor, needing to use the specific servo horns provided with them. I have a box full of servos, different…
  • aspork42
    aspork42 over 2 years ago +1
    Very cool! This is like 2, 3, or 4 projects all in one. Nice work!
  • dang74
    dang74 over 2 years ago in reply to aspork42

    I totally agree.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • dang74
    dang74 over 2 years ago

    Very ambitious project.  Definitely a good demonstration of combining electronic and mechanical disciplines to create something really cool and nostalgic.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • robogary
    robogary over 2 years ago

    Another item of interest, the center of the stainless steel dryer drum back had to be cutout. A dremel tool with the reddish abrasive cutting wheels was used to make the cut. Diamond dremel wheel blades didnt do a great job, 3 tool bit shafts snapped before changing the cutting wheel type. The reddish abrasive wheels did great, but only lasted for about 3 linear inches. An entire tube of the reddish grinding wheels were consumed in making the cutout.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • aspork42
    aspork42 over 2 years ago

    Very cool! This is like 2, 3, or 4 projects all in one. Nice work!

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • robogary
    robogary over 2 years ago

    I also learned that 9g servos have a different output shaft radius and # of teeth depending on the vendor, needing to use the specific  servo horns provided with them. I have a box full of servos, different sizes and vendors, all mixed together and couldnt find matching servo horns. I had to tear down the 2022 Halloween project to scavenge more servos and servo horns. 

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
>
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube