# TOS E Warp Engine Lighting Effect - Custom Solution



## RossW (Jan 12, 2000)

Almost 5 years in the making, here's my TOS E warp engine lighting solution available to all who are willing to put it together themselves. I'm providing the Arduino code (thanks Gadgetron_3000 for your post on LEDFader library - that was the crucial missing part and convinced me to switch from PIC Microcontrollers to Arduino), PCB boards (which you'll use to order yourself from places like OSH Park in the U.S.), schematics, parts list, and photos of the completed set up.

This is free for individual modellers to use, but not for sale by anyone other than me. So, it's OK to put a set together for a friend if they're not comfortable with soldering SMD components, but please do not sell them.

While I would have preferred to use 1 board to light both nacelles, that would mean running 9 wires up the nacelle pylons (7 for this board and another 2 for the motor). Not impossible, but my pylons are already glued together so the Arduino logic board will fit in the nacelle (my rear caps are removable and held in place my small magnets).

The Arduino logic board needs a regulated 5V power supply, so if you're using 9V for the port lights you'll need a 5V regulator board. I got mine from Pololu.com. It handles both the blinking LEDs (my board has 15 blinkies - 5 larger ones and 10 SMDs) and the 5 pulsing amber LEDs. I found that rectangular LEDs look the best but you could substitute 3mm or 5mm round ones if desired. The fade up/down time and intensity is randomly set in each iteration through the loop. The min/max values were chosen after much experimentation so that the blinkies don't overwhelm the ambers, but also don't disappear. Same goes for each resistor value chosen for the LEDs - not too bright but not too dim. This is also affected by how you finish the two domes - for mine, I sprayed a very light coat of Tamiya Clear Orange in the inside of the outer dome (after gently frosting the insides), and a heavier coat on the spinning inner dome. The blades are Bare Metal Foil (Chrome) - black is too dark for this scale, IMHO.

You can use different coloured blinking LEDs between the port an starboard nacelles, either just by rearranging the ones I used or using different colour combinations. Just be careful with he series resistors and test with your completed clear domes.

The board in the photos has a 3-pin JST connector to provide power, and a small slider switch to control what makes the amber LEDs pulse - I have a separate board for controlling the motors and that also includes a separate chip to control the amber LEDs - but the schematics and parts list reflect a 2-pin JST connector to simplify things for everyone else, so go by the schematics and parts list.

Here's a YouTube vide of the whole shebang in action: 




Arduino sketch:

```
/*

Copyright (c) 2017 Ross A. Waddell

Sketch is for personal use only. 


Change:

  Board -> Ardunio Pro or Pro Mini
  Processor -> ATmega328 (5V, 16Mhz)
  Port -> (whichever one has "usb" in it; board needs to be connected)
  Programmer -> AVRISP mkII


http://scifimodelaction.com/sfmaforum/index.php?topic=6850.msg88253#msg88253

  5 LED Random Intensity and Time Fader:

    - Fades five LEDs to random intensities (between 0 to 255) at random
      durations (between 0 to 1.5 seconds).

    - The LEDFader.h library will be needed.  The download and instructions can be found
      here: https://github.com/jgillick/arduino-LEDFader.

    - Based on original Arduino sketch by Jeremy Gillick
      (http://mozmonkey.com/2013/10/arduino-fade-leds-without-blocking/).

*/

#include <LEDFader.h>              // Don't forget to include the LEDFader libraries folder
#include <Curve.h>

// Config for blinking coloured LEDs
// =================================
#define LED_NUM 5                  // Number of LEDs

// 5 pin blinking LED setup
LEDFader leds[LED_NUM] = {
  LEDFader(3),                     // PWM pin
  LEDFader(5),                     // PWM pin
  LEDFader(6),                     // PWM pin
  LEDFader(9),                     // PWM pin
  LEDFader(10),                    // PWM pin
};

unsigned long OffTimerLEDs[LED_NUM];


// Config for pulsing amber LEDs
// =============================
#define AMBER_LED_PIN 11           // Amber LEDs output pin (5 in pentagon shape)
#define FADE_UP_TIME 2500          // Time to power up (power first turned on)
#define PULSE_TIME 600             // Fade down/up pulse time
#define MAX_BRIGHTNESS 200//190         // Max brightness of amber LEDs (can go up to 255)   -> 190 works well
#define MIN_BRIGHTNESS 185//175         // Min brightness of amber LEDs to fade down to (pulse)   -> 175 works well
#define DIR_UP 1
#define DIR_DOWN -1

LEDFader amber_led;
int direction = DIR_UP;


void setup() {
  randomSeed(analogRead(0));

  amber_led = LEDFader(AMBER_LED_PIN);
  amber_led.set_curve(&Curve::exponential);
  amber_led.fade(MAX_BRIGHTNESS, FADE_UP_TIME);
}
 
void loop() {

  // Pulsing amber LEDs
  // ==================

  amber_led.update();

  // LED no longer fading, switch direction
  if (amber_led.is_fading() == false) {

    if (direction == DIR_UP) {
      // Last faded up, so now fade down
      amber_led.fade(MIN_BRIGHTNESS, PULSE_TIME);
      direction = DIR_DOWN;
    }
    else {
      // Last faded down, so now fade up
      amber_led.fade(MAX_BRIGHTNESS, PULSE_TIME);
      direction = DIR_UP;
    }
  }


  // Blinking coloured LEDs
  // ======================
  
  unsigned long currentMillis = millis();


  // Update all LEDs and start new fades if any are done
  for (byte i = 0; i < LED_NUM; i++) {
    LEDFader *led = &leds[i];
    led->update();
 
    if (led->is_fading() == false) {
      // This LED is not fading, start a new fade

      // LED has stopped fading down (hopefully, we are capturing this just as it has ended)
      // Set timer for how long LED should stay off (if not set already)
      if (led->get_value() == 0 && OffTimerLEDs[i] == 0) {
        int offTime = random(100, 350);

        OffTimerLEDs[i] = millis() + offTime;
      }  
 
      int duration = random(95, 700);             // Randomly set fade duration between 95 to 700 ms (0.7 s)
      // int duration = random(75, 700); -> alternate timings; use what best suits you
      // int duration = random(100, 750);
      // int duration = random(0, 750);
      // int duration = random(1000, 3000);
 
      if (led->get_value() == 0 && currentMillis > OffTimerLEDs[i]) {
        // Was fading down, so now fade up (but only if the elapsed time for the off value has been exceeded)
        OffTimerLEDs[i] = 0;
        
        byte intensity = random(7, 15);           // Randomly set brightness intensity between 7 and 15
                                                  // PWM: 0 (off) to 255 (maximum)
        // byte intensity = random(5, 15); -> alternate intensities; use what best suits you
        // byte intensity = random(15, 50);
        // byte intensity = random(0,75);
        // byte intensity = random(100, 255);

        led->fade(intensity, duration);
      }
      else {        
        // Was fading up, so now fade down
        led->fade(0, duration);
      }
    }
  }
}
```
Note - you need to grab the LEDFader library from GitHub as mentioned in Gadgetry_3000's post (link to that topic is in the code above).

Fritzing schematic:
TOS E Warp Engines (Arduino Pro Mini) by Ross the Boss, on Flickr

Arduino logic board:
Arduino_Logic_Board_Front by Ross the Boss, on Flickr

Nacelle disc:
Nacelle_Disc_Front by Ross the Boss, on Flickr

All the files you need are in my Google Drive folder:
https://drive.google.com/open?id=0B-ikhAQea-PaU1dtTGxSa2pDQU0

Happy modelling!


----------



## RICHjm (Jun 14, 2010)

I'm assuming this is for the 1/350 scale TOS 1701.


----------



## RossW (Jan 12, 2000)

RICHjm said:


> I'm assuming this is for the 1/350 scale TOS 1701.


Correctamundo.


----------



## Fozzie (May 25, 2009)

Beautiful job all around. The PCB looks great and the effect is outstanding. Congrats!


----------



## RossW (Jan 12, 2000)

Thanks Fozzie!


----------



## charonjr (Mar 27, 2000)

Fozzie, thank you! I am just starting to learn Arduino code. I have one in my 3D printer and have modified the scripts for a new controller.

You just gave me new impetus to continue learning!

David in Tucson


----------



## MisterM (Oct 17, 2009)

I was lamenting the discontinue of the R2 lighting kit. This is so much better and I get to practice soldering. Thanks very much for doing this. It is much appreciated!


----------



## RossW (Jan 12, 2000)

MisterM said:


> I was lamenting the discontinue of the R2 lighting kit. This is so much better and I get to practice soldering. Thanks very much for doing this. It is much appreciated!


You're welcome MisterM!


----------



## Fozzie (May 25, 2009)

charonjr said:


> Fozzie, thank you! I am just starting to learn Arduino code. I have one in my 3D printer and have modified the scripts for a new controller.
> 
> You just gave me new impetus to continue learning!
> 
> David in Tucson


I got into Arduino to light up models and have ended up doing a whole lot more with it. Lots and lots of possibilities...!


----------



## littleyoda99 (Jul 11, 2016)

that is a thing of beauty. I wish I could retrofit those into my nacelles, but alas....

maybe my next build!


----------



## RossW (Jan 12, 2000)

Thanks littleyoda99!


----------



## jgoldsack (Apr 26, 2004)

I suppose I should start using my original account again...lol forgot I was logged in as that one.


----------



## MHaz (Aug 18, 1999)

Can this be adapted for the 22" cutaway? I know your circuit boards are sized for the 350th kit, but if a little redesign is done, could it work?


----------



## RossW (Jan 12, 2000)

MHaz said:


> Can this be adapted for the 22" cutaway? I know your circuit boards are sized for the 350th kit, but if a little redesign is done, could it work?


You would probably have to remove some of the LEDs/resistors to fit, but anything is possible.


----------



## Rahn (Jun 2, 2009)

Great work.

When I refer to the PDF file with the PCB layout, both sides are superimposed on one page. It makes it difficult to decipher.

How/where do you have the PCBs made?


----------



## RossW (Jan 12, 2000)

Rahn said:


> Great work.
> 
> When I refer to the PDF file with the PCB layout, both sides are superimposed on one page. It makes it difficult to decipher.
> 
> How/where do you have the PCBs made?


I get my PCBs from OSH Park, located in the U.S. Free shipping to U.S. and Canada.

The pdfs of the boards do show both sides, but have a look at the photos of the boards to compare.


----------



## Rahn (Jun 2, 2009)

Maybe I'm confused.

When I look at the PDF, both side are there, but combined/mixed together on one page (rather than two).

I even tried to edit the PDF (CorelDraw) to separate the two sides, but they're not grouped in a way that made it easy to separate.

I started comparing to the photos and deleting one piece at a time to make them the match, assuming red is one side, and blue the other.

I was only pointing it out to possibly help the next person who may not have editing ability.


----------



## RossW (Jan 12, 2000)

Rahn said:


> Maybe I'm confused.
> 
> When I look at the PDF, both side are there, but combined/mixed together on one page (rather than two).
> 
> ...


You're not confused - red lines/parts are on the top side, blue on the bottom. Harder to tell with some of the other components, but by looking at the photos you can see what's where.

But why do you need to separate the top/bottom on the pdfs? What info are you looking for? They're just there for additional info, you don't need them to get boards made.


----------



## Rahn (Jun 2, 2009)

I work in printing, but not knowledgeable about PCBs.

I thought of the PDF as 'artwork' that is used to 'print' the PCB.

Therefore, art for side one and art for side two, respectively.


----------



## RossW (Jan 12, 2000)

Ah. But all you really need is the Eagle .brd file in the PCB folder, or the Gerber zip.


----------



## Opus Penguin (Apr 19, 2004)

Awesome work!


----------



## RossW (Jan 12, 2000)

Opus Penguin said:


> Awesome work!


Thank you!


----------



## Indy5000 (Sep 23, 2017)

Nice work! Arduino is definitely the way to go.


----------



## taneal1 (Jul 27, 2014)

RossW said:


> This is free for individual modellers to use, but not for sale by anyone other than me. So, it's OK to put a set together for a friend if they're not comfortable with soldering SMD components, but please do not sell them.


Ross,

Absolutely awesome work!

And THANK YOU for allowing others to reap the benefit of your hard work. Few are so generous...

Tom


----------



## RossW (Jan 12, 2000)

taneal1 said:


> Ross,
> 
> Absolutely awesome work!
> 
> ...


Thanks very much, Tom!


----------



## RossW (Jan 12, 2000)

BTW, I will soon be posting my board and code for the main TOS E board that controls the blinking running lights (saucer), the strobes on the rear sides of the secondary hull, and the warp engine motor speed controller - all in one! Just need to get the prototypes back from the PCB house and do a video or two.


----------



## jgoldsack (Apr 26, 2004)

How much woudl it cost for an assembled set of boards?


----------



## RossW (Jan 12, 2000)

jgoldsack said:


> How much woudl it cost for an assembled set of boards?


I'm not really set up for building these for anyone else; I have so much on the go that I rarely get time to work on my own projects, which is why I'm posting this as DYI.


----------



## Neverendingmods (May 31, 2006)

Holy Cow, that's nice-lookin'!


----------



## daytime dave (Jan 14, 2017)

That's a very nice accomplishment. Nice work.

It's also really nice that you are sharing all your hard work. Very nice indeed.


----------



## RossW (Jan 12, 2000)

Neverendingmods said:


> Holy Cow, that's nice-lookin'!


Thanks!


----------



## RossW (Jan 12, 2000)

daytime dave said:


> That's a very nice accomplishment. Nice work.
> 
> It's also really nice that you are sharing all your hard work. Very nice indeed.


Thank you!


----------



## RossW (Jan 12, 2000)

As promised, here’s a preview of my custom motor control circuit board that lets you set the motor speed and direction (in case you wire up one or both motors so that they don’t spin in the direction you want, or you want them to spin in the same direction instead of the usual opposite). In addition, the Arduino Pro Mini code includes the blinking saucer/running lights and secondary hull strobes, and also provides the +5V power for the nacelle circuit boards.






I’ll be doing a separate post later on that has all the code, schematic and board design details.


----------



## charonjr (Mar 27, 2000)

This is so nice to see! (Edit) I .... love....what you are doing.


----------



## RossW (Jan 12, 2000)

charonjr said:


> This is so nice to see!


Thank you charonjr!


----------



## Fozzie (May 25, 2009)

As an Arduino man myself, I'm very interested in this project. You've done a great job here.


----------



## RossW (Jan 12, 2000)

Fozzie said:


> As an Arduino man myself, I'm very interested in this project. You've done a great job here.


Thanks Fozzie!


----------



## Alien (Sep 5, 2001)

Ross,

You are THE MAN. It is fantastic that you have open-sourced all your hard work so others may ride on your coat tails. Like me!

I am about to get into my Enterprise kit again and I was about to start designing a PCB for the nacelles so thank you very much for your work. I am in awe!!

BTW. I am a user of OSHPark too. Do you know that you can share your PCB designs on their site so others can get them made directly? No need to download your Gerber files and then upload them again. (Obviously having direct access to the Gerbers is required if others want to use a different PCB fabricator.)

Thanks again
Alien


----------



## RossW (Jan 12, 2000)

Alien said:


> Ross,
> 
> You are THE MAN. It is fantastic that you have open-sourced all your hard work so others may ride on your coat tails. Like me!
> 
> ...


Thanks Alien for the kind words!

I did NOT know I could share my board on OSHPark - I will have to look into that during the holidays.


----------



## Alien (Sep 5, 2001)

Ross,

Just a bit of bad news. Your ZIP file of all the Gerbers is missing the Board Outline file so OSHPark rejects it as being incomplete.

I have a copy of Eagle so I just regenerated the all the Gerbers from your BRD file but others will be stuck.. 

Doh! I hate it when that happens. This sort of thing has never happened to me! Oh no no no no no... Yes! :frown2:

Alien


----------



## RossW (Jan 12, 2000)

Alien said:


> Ross,
> 
> Just a bit of bad news. Your ZIP file of all the Gerbers is missing the Board Outline file so OSHPark rejects it as being incomplete.
> 
> ...


Hmm. I'm using the Eagle CAM job add-in from Sparkfun to generate the Gerbers, so it should be fine. But the good news is that with OSHPark, you can just use the Eagle .brd file directly - that's what I use when ordering PCBs from them.

Edit: I just checked the zip file and it does have the 7 files needed as indicated on the SparkFun tutorial (https://learn.sparkfun.com/tutorials/using-eagle-board-layout/generating-gerbers) - which one do you think is missing? Also, is this for the Main board or for the Warp Engine Lights?


----------



## Alien (Sep 5, 2001)

Ross,
I was looking at your PCB designs for the Warp Engine lights but the Main board still only contains 7 Gerbers in the Zip file.

Typically you need eight Gerber files for a two sided board.

Two of each of the following: (Top side and bottom side)
Copper Layer
Solder Mask 
Silk Screen 

And then one each of:
Drill file
Board Outline

Obviously you do not technically need either of the silkscreen layers (If you don't want text printed on your board) but OSHPark actually requires you to have both (At least it used to.)

I forgot I could just upload the Eagle .BRD file to OSHPark. That would work OK but not all fabricators accept that format.

Alien


----------



## RossW (Jan 12, 2000)

Alien said:


> Ross,
> I was looking at your PCB designs for the Warp Engine lights but the Main board still only contains 7 Gerbers in the Zip file.
> 
> Typically you need eight Gerber files for a two sided board.
> ...


I can re-run the Gerber job and upload a new version, but the PCB house in China I used to go to (Seeed) only wanted those 7. Depends on the board house, I guess.


----------



## Alien (Sep 5, 2001)

Yes, you are probably correct about your other boards when using Seeed.
If you put dashed lines around the edge of your board, like you have done with the Warp engine board, then they may have just used that to determine where to cut. I would guess that your PCB was rectangular in that case.
For more complex shapes, even a circular board, the Outline layer is very necessary to get the exact size and shape that you expect. Even with your Warp engine board, the circular size is critical so it fits neatly into the plastic kit part.

Alien


----------



## Alien (Sep 5, 2001)

Yahoo, my PCB's (Actually yours Ross! :wink2 have just been assigned to a Panel by OSHPark. They will be warping their way to me in a few days..

I am not going to use an Arduino to control the LEDs. I will program up a PIC using your C code as a timing guide. The PIC will also drive my stepper motor to rotate the 'fans'. I will make two of these, one for each nacelle, so I will just have to feed 3 wires up the pylons. (+5v, Gnd, Control)

I can't wait to get soldering LEDs.

Alien


----------



## RossW (Jan 12, 2000)

Alien said:


> Yes, you are probably correct about your other boards when using Seeed.
> If you put dashed lines around the edge of your board, like you have done with the Warp engine board, then they may have just used that to determine where to cut. I would guess that your PCB was rectangular in that case.
> For more complex shapes, even a circular board, the Outline layer is very necessary to get the exact size and shape that you expect. Even with your Warp engine board, the circular size is critical so it fits neatly into the plastic kit part.
> 
> Alien


Same circular board done at Seeed. There is an outline drawn which may not show up when you import the .brd file depending on your layer selection (the dashed lines are the top/bottom ground planes). Most board houses I've used were fine with the CAM processing file from SparkFun, but I've grabbed OSHPark's CAM file and re-generated the Gerber files:

https://drive.google.com/open?id=1LThs2QHAyI25nojLE3e3Y1OMUnPcLUUL

https://drive.google.com/open?id=1Hl4OCEEfZ78o_HBUjJeH2Lp4P5O99jEJ


----------



## RossW (Jan 12, 2000)

Alien said:


> Yahoo, my PCB's (Actually yours Ross! :wink2 have just been assigned to a Panel by OSHPark. They will be warping their way to me in a few days..
> 
> I am not going to use an Arduino to control the LEDs. I will program up a PIC using your C code as a timing guide. The PIC will also drive my stepper motor to rotate the 'fans'. I will make two of these, one for each nacelle, so I will just have to feed 3 wires up the pylons. (+5v, Gnd, Control)
> 
> ...


If you're using PICs (which is what I started with before switching to Arduino), note that you must use a NPN transistor to power the LEDs as the connections on the board expect that. The ULN2803 has 8 input/output pairs so should work fine on your board, too.


----------



## Alien (Sep 5, 2001)

Ross,

Oh YES! We do need that driver as the little Microcontroller chips cannot supply the power required by all the LEDs.

I am going to use a ULN2003. Pretty much the same as the ULN2803 but only has 7 Darlington driver transistors. I just happen to have a stack of them in a drawer all screaming "Use me, use me"
And I will also have to add a stepper motor driver chip to spin my micro stepper motors.

Question.....
Why did you choose rectangular orange LEDs for the 5 main lights??
Did the rectangular shape light pattern look better than a standard round 3mm LED?

Alien


----------



## RossW (Jan 12, 2000)

Alien said:


> Question.....
> Why did you choose rectangular orange LEDs for the 5 main lights??
> Did the rectangular shape light pattern look better than a standard round 3mm LED?
> 
> Alien


I've been working on this lighting design for many years now, and up until this summer I always used round 5mm amber LEDs. But when I tried rectangular, I couldn't believe how much better it looked:

*Rectangular*





*Round*





But your mileage may vary - you can use either in my board.


----------



## RossW (Jan 12, 2000)

Alien said:


> Ross,
> 
> Oh YES! We do need that driver as the little Microcontroller chips cannot supply the power required by all the LEDs.
> 
> ...


What do you use to program your PICs? I use PICBasicPro and have pretty decent code for the blinkies and the pulsating ambers, if you're interested. I can also give you the compiled assembly language files, too.


----------



## Trekkriffic (Mar 20, 2007)

RossW said:


> I've been working on this lighting design for many years now, and up until this summer I always used round 5mm amber LEDs. But when I tried rectangular, I couldn't believe how much better it looked:
> 
> *Rectangular*
> https://youtu.be/ff37t7IXv8A
> ...


Interesting. The blue and red LEDs merge to form a purple color when the spoked dome is placed over them. Hmmmmm....


----------



## RossW (Jan 12, 2000)

Trekkriffic said:


> Interesting. The blue and red LEDs merge to form a purple color when the spoked dome is placed over them. Hmmmmm....


There is a pink flashing LED in there, too. May be more than one. I played around with different colours quite a lot.


----------



## Alien (Sep 5, 2001)

RossW said:


> What do you use to program your PICs? I use PICBasicPro and have pretty decent code for the blinkies and the pulsating ambers, if you're interested. I can also give you the compiled assembly language files, too.


Ross,
I use Microchips PICKit3 programmer and that has a C compiler as well as an Assembler compiler.
I am a computer nerd and I learned to program in Assembler back in the '80's. The PIC's RISC based instruction set only has 36 instructions to learn, so I tend to use Assembler especially when doing things like PWM for lighting control where timing can be critical.
People tell me that only masochists use Assembler but I quite like it. C has always annoyed me with all its semicolons and curly brackets. 

Thanks for the offer of a PICBasic file. I would love to see what you have done, even if I cannot use it as I don't use PIC Basic. 
(I think that your compiled Assembly code will just be a big file of hexadeimal characters so it will not be of much use unless I was going to load it into the same model PIC chip that you used. ) 

I have written quite a few routines that fade LEDs up and down using PWM so that will not be a problem. It will me more of an effort to integrate the drive clocking for the stepper motors within fading up and down of the LEDs. 

Thanks for the info on the rectangular LEDs. I have some 3mm orange flat top LEDs (Like they use for Christmas tree lights.) I might give them a go and see what they look like. I will just go and buy rectangular ones if they don't look any good.

Alien


----------



## RossW (Jan 12, 2000)

Alien said:


> Ross,
> I use Microchips PICKit3 programmer and that has a C compiler as well as an Assembler compiler.
> I am a computer nerd and I learned to program in Assembler back in the '80's. The PIC's RISC based instruction set only has 36 instructions to learn, so I tend to use Assembler especially when doing things like PWM for lighting control where timing can be critical.
> People tell me that only masochists use Assembler but I quite like it. C has always annoyed me with all its semicolons and curly brackets.
> ...




```
'****************************************************************
'* Name : Nacelle_Blinking_Lights_12F1840_8Mhz_Int.pbp *
'* Author : Ross A. Waddell *
'* Notice : Copyright (c) 2016 *
'* : All Rights Reserved *
'* Date : 06/23/2016 *
'* Version : 5a (starboard engine) *
'* Notes : Blinking nacelle engine lights (TOS Enterprise) *
'* : *
'****************************************************************

' ==============================================================================
' Code provided by Darrel Taylor
' See Darrel's posting on my thread:
' http://www.picbasic.co.uk/forum/showthread.php?t=17299&p=126141#post126141

' MIBAM discussions:
' http://www.picbasic.co.uk/forum/content.php?r=217-MIBAM-(Mirror-Imaged-Bit-Angle-Modulation)
' http://www.picbasic.co.uk/forum/showthread.php?t=10564&highlight=MIBAM
' http://www.picbasic.co.uk/forum/content.php?r=537-MIBAM-(Mirror-Imaged-Bit-Angle-Modulation)
' http://www.picbasic.co.uk/forum/content.php?r=538-MIBAM-More-Info

' Temporary Central Repository of DT's code:
' http://www.picbasic.co.uk/forum/showthread.php?t=19638&highlight=MIBAM

' ==============================================================================


' TODO:
' ----
' - set up starboard/port with slightly different blink rates
' - after finalizing nacelle domes, adjust brightness of blinking LEDs



' Nacelle engine lights
' ==============================================================================
' (a) The colours used were: red, blue, green, amber and pink, all standard =
' colours they had for common Christmas lights of the time. =
' (b) They were all Christmas lights (C7, too big for a 1/350). 12 by my guess.=
' (c) Amber were the steady-on (i.e. non-bliking) lights (5 in a star pattern),=
' all the rest blinked. =
' ==============================================================================

' Basic blinky code provided by Darrel Taylor
' See forum posting here:
' http://www.picbasic.co.uk/forum/showthread.php?t=17299&p=116934#post116934

' ***************************************************************
' Pin Connections
' ***************************************************************

' VDD -> pin 1 -> +5V
' RA5 -> pin 2 -> R7 -> BL4
' -> R8 -> BL4a
' RA4 -> pin 3 -> R9 -> BL5
' -> R10-> BL5a
' RA2 -> pin 5 -> R1 -> BL1
' -> R2 -> BL1a
' RA1 -> pin 6 -> R3 -> BL2
' -> R4 -> BL2a
' RA0 -> pin 7 -> R5 -> BL3
' -> R6 -> BL3a
' VSS -> pin 8 -> GND


' For SMD PICs, need to add a 2pos SPST DIP swich between RA0/RA1 and the LED
' resistor; for ICSP, flip the switches to open the connection (otherwise, the
' U2 programmer will power the LEDs as it's programming the chip and it may not
' save the new code).

DEFINE OSC 8

' ***************************************************************
' Initialization
' ***************************************************************

' For production version of this code, update config fuses to 
' enable code protect (CP_ON)
#CONFIG
__config _CONFIG1, _FOSC_INTOSC & _WDTE_ON & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF
__config _CONFIG2, _PLLEN_OFF & _STVREN_ON & _BORV_LO & _LVP_OFF
#ENDCONFIG

OSCCON = %01110000 ; 8MHz internal osc
TRISA = 0	; Make all pins output
ANSELA = 0 ; All digital
FVRCON = 0 ; Fixed Voltage Reference is disabled

CM1CON0.7 = 0 ; Comparator is disabled
OPTION_REG = %00000110 ; Timer0 prescaler 1:128
TMR0IF VAR INTCON.2 ; Timer0 Overflow bit

;----[ MIBAM Setup - START ]------------------------------------------------

;--[For 14-bit cores only (12F, 16F, NOT 16F1's]----------------------------
;-- Place a copy of these variables in your Main program -------------------
;-- The compiler will tell you which lines to un-comment --
;-- Do Not un-comment these lines in this file --
;---------------------------------------------------------------------------
;wsave VAR BYTE $20 SYSTEM ' location for W if in bank0
;wsave VAR BYTE $70 SYSTEM ' alternate save location for W 
' if using $70, comment wsave1-3

' --- IF any of these three lines cause an error ?? ------------------------
' Comment them out to fix the problem ----
' -- Which variables are needed, depends on the Chip you are using -- 
;wsave1 VAR BYTE $A0 SYSTEM ' location for W if in bank1
;wsave2 VAR BYTE $120 SYSTEM ' location for W if in bank2
;wsave3 VAR BYTE $1A0 SYSTEM ' location for W if in bank3
' --------------------------------------------------------------------------
BAM_COUNT CON 5 ; How many BAM Pins/LEDs are used?

INCLUDE "MIBAM.pbp" ; Mirror Image BAM module

DEFINE BAM_INFO 1
DEFINE _BAM_FREQ 100 ; Code will automatically pick max freq;
; (only set this if a lower value is desired)

Bright VAR BYTE[BAM_COUNT]
Br0 VAR Bright[0]
Br1 VAR Bright[1]
Br2 VAR Bright[2]
Br4 VAR Bright[3]
Br5 VAR Bright[4]

ASM
BAM_LIST macro ; Define PINs to use for BAM
BAM_PIN (PORTA,0, Br0) ; BL3 and the associated duty variables
BAM_PIN (PORTA,1, Br1) ; BL2
BAM_PIN (PORTA,2, Br2) ; BL1
BAM_PIN (PORTA,4, Br4) ; Bl5
BAM_PIN (PORTA,5, Br5) ; BL4
endm
BAM_INIT BAM_LIST ; Initialize the pins
ENDASM

;----[ MIBAM Setup - END ]--------------------------------------------------

; BL3,BL2,BL1,BL5,BL4 ; PCB labels for blinking LEDs
OnTimes DATA 9, 22, 33, 10, 15 ; default periods for each output
OffTimes DATA 25, 45, 25, 10, 33
'OffTimes DATA 35, 45, 30, 95, 22

; MIBAM only works well in this situation when the Brightness values
; are relatively low; too high and it throws the timing off for the on/off
; blinking.
Brightness DATA 20, 10, 20, 10, 10 ; GOOD
'Brightness DATA 120, 72, 60, 54, 42 ; GOOD
'Brightness DATA 150, 72, 60, 54, 9 ; TESTING

temp VAR WORD ; temp variable to hold brightness value
; read from DATA table
fadeLowMIBAM CON 1 ; fade inc/dec for low MIBAM values
fadeMedMIBAM CON 3 ; fade inc/dec for medium MIBAM values
fadeHighMIBAM CON 6 ; fade inc/dec for high MIBAM values
fadeVal VAR BYTE ; calculated fade value in loop

#DEFINE USE_RANDOM_SEQUENCE ; comment for contiuous sequence

#IFDEF USE_RANDOM_SEQUENCE
RND VAR WORD : RND = 13864
MIN_ON CON 9 ; Minimum random ON time
MAX_ON CON 42 ; Maximum random ON time
MIN_OFF CON 9 ; Minimum random OFF time
MAX_OFF CON 45 ; Maximum random OFF time
RandPeriod VAR WORD[BAM_COUNT]
RandPeriods DATA WORD 1000, WORD 1250, WORD 1500, WORD 1750, WORD 2000
#ENDIF

;----[Variables used only by Blinky]-----------------------------
LoopLED VAR WORD[BAM_COUNT]
OnTime VAR WORD[BAM_COUNT]
OffTime VAR WORD[BAM_COUNT]
x VAR BYTE

;----[Initialize]------------------------------------------------
FOR x = 0 to (BAM_COUNT - 1) 
READ OnTimes+x, OnTime(x)
READ OffTimes+x, OffTime(x)
#IFDEF USE_RANDOM_SEQUENCE
READ RandPeriods+(x<<1), WORD RandPeriod(x)
#ENDIF
NEXT X

;----[Main Program Loop]----------------------------------------
Main:
x = (x + 1) // BAM_COUNT
' Non-fade-in/out loop
' ====================
' IF LoopLED(x) < OnTime(x) THEN
' READ Brightness + x, Bright(x)
' ELSE
' Bright(x) = 0
' ENDIF

' Fade-in/out loop (only seems to work with OSC=8Mhz)
' ===================================================
READ Brightness + x, temp

' Set fade up/down value
IF temp < 10 THEN
fadeval = fadeLowMIBAM
ELSEIF temp < 70 THEN
fadeval = fadeMedMIBAM
ELSE
fadeval = fadeHighMIBAM
ENDIF

IF LoopLED(x) < OnTime(x) THEN
IF Bright(x) < temp THEN
Bright(x) = Bright(x) + fadeval
ELSE
Bright(x) = temp
ENDIF
ELSE
IF Bright(x) > 0 THEN
Bright(x) = Bright(x) - fadeval
ELSE
Bright(x) = 0
ENDIF
ENDIF

LoopLED(x) = (LoopLED(x) + 1) // (OnTime(x) + OffTime(x))
#IFDEF USE_RANDOM_SEQUENCE
RandPeriod(x) = RandPeriod(x) - 1
IF RandPeriod(x) = 0 THEN
READ RandPeriods+(x<<1), WORD RandPeriod(x)
RANDOM RND
OnTime(x) = (MAX_ON - MIN_ON)* RND.HighByte / 255 + MIN_ON
OffTime(x)= (MAX_OFF - MIN_OFF)* RND.LowByte / 255 + MIN_OFF
ENDIF
#ENDIF

IF x != (BAM_COUNT - 1) THEN Main

Waiting: IF !TMR0IF THEN Waiting
TMR0 = 99
TMR0IF = 0
GOTO Main
```


----------



## Alien (Sep 5, 2001)

Brilliant. Thanks Ross

Alien


----------



## Y3a (Jan 18, 2001)

Sooooo, I JUST got back from watching the 11 foot TOS E at the Smithsonian. Got there about 2 minutes before it lit up. I was amazed at how good it looks lit. The nacelles were less bright than I thought they would be. Ross, your solution looks great!


----------



## Alien (Sep 5, 2001)

Y3a said:


> Sooooo, I JUST got back from watching the 11 foot TOS E at the Smithsonian. Got there about 2 minutes before it lit up. I was amazed at how good it looks lit. The nacelles were less bright than I thought they would be. Ross, your solution looks great!


Boy am I jealous?? The Smithsonian is a long and expensive bus ride from New Zealand.

Alien


----------



## RossW (Jan 12, 2000)

Y3a said:


> Sooooo, I JUST got back from watching the 11 foot TOS E at the Smithsonian. Got there about 2 minutes before it lit up. I was amazed at how good it looks lit. The nacelles were less bright than I thought they would be. Ross, your solution looks great!


Thanks very much!


----------



## RossW (Jan 12, 2000)

Alien said:


> Boy am I jealous?? The Smithsonian is a long and expensive bus ride from New Zealand.
> 
> Alien


You’d have to hold your breath for a fair bit, but it’d be so worth it.


----------



## Milton Fox Racing (May 27, 2014)

Alien said:


> Boy am I jealous?? The Smithsonian is a long and expensive bus ride from New Zealand.
> 
> Alien


Did you check with Uber? :lurk5:


----------



## Alien (Sep 5, 2001)

Uber couldn't give me a price.:laugh: But at least I could stop for Uber Eats along the way.
Uber big price tag though.:crying:
And I would have to talk to William Trubridge about how to hold my breath. (He is the Kiwi who holds the world record for free diving. 4mins 14secs on a single breath and he swims down to 102 metres/334.6 feet)
I am turning blue just thinking about it.

I wonder if Peter Jackson's private jet is in its hanger at Wellington Airport? Fly me to Washington.

Alien


----------



## Y3a (Jan 18, 2001)

Alien said:


> Boy am I jealous?? The Smithsonian is a long and expensive bus ride from New Zealand.
> 
> Alien


yeah.I wanted to go to see the restored Beyer-Garrett locomotive but can't for the same reasons. I'm a big fan of Team New Zealand & Black Magic!


----------



## Alien (Sep 5, 2001)

Y3a said:


> yeah.I wanted to go to see the restored Beyer-Garrett locomotive but can't for the same reasons. I'm a big fan of Team New Zealand & Black Magic!


Start saving those penny's and try to come across for the 2021 Americas Cup. Team NZ will be defending the Cup in Auckland. You can then jump across the Tasman and go see the Beyer-Garrett in Aussie.

Alien


----------



## Alien (Sep 5, 2001)

My PCB's have arrived from OSHPark. Nicely done Ross:thumbsup:
Some SMD pink LEDs turned up in the post today too. 
I still need a few more bits and pieces and some time. (Even though I have been told I already have all the time there is!!)

Alien


----------



## RossW (Jan 12, 2000)

Excellent! Can’t wait to see them all done up!


----------



## Voyager (Dec 30, 2017)

Ross W. - Hi, newbie here. Just learning this arduino thing. I like this project a lot! I downloaded your Google Drive files. Do you have pics of the pcbs that I can use to try to etch my own boards? I don't have anything that opens gerber(?) files. Thanks!


----------



## Voyager (Dec 30, 2017)

found gerbv and opened the files. K, pretty, but dont know how to make this into something to etch a pcb. guess a lot to learn. thought it was just pics you expose to each side of the board....


----------



## RossW (Jan 12, 2000)

Voyager said:


> found gerbv and opened the files. K, pretty, but dont know how to make this into something to etch a pcb. guess a lot to learn. thought it was just pics you expose to each side of the board....


Hi Voyager - are you trying to burn your own PCBs? I don’t think that will work with my boards as each layer (top and bottom) has a GND plane; that wouldn’t come across in a picture. But if you use the .brd file you can upload that to OSHPark and get 3 boards made for you relatively inexpensively.


----------



## Voyager (Dec 30, 2017)

Ok, thanks! I want to play with making my own, but I yeah here , I will order.


----------



## Alien (Sep 5, 2001)

Voyager said:


> Ok, thanks! I want to play with making my own, but I yeah here , I will order.


Voyager,

Yes you are better off ordering the boards from OSHPark or another fabricator. You can get PCBs made for so little money these days it is hardly worth trying to do it yourself.
In addition, Ross's PCBs are double sided, which is hard to do yourself. They also have 'Vias' (Links between the top and bottom copper layers) that are almost impossible to do yourself. You have to resort to soldering wires between the top and bottom tracks. Ugly!:frown2:

Alien


----------



## RossW (Jan 12, 2000)

Alien said:


> Voyager,
> 
> Yes you are better off ordering the boards from OSHPark or another fabricator. You can get PCBs made for so little money these days it is hardly worth trying to do it yourself.
> In addition, Ross's PCBs are double sided, which is hard to do yourself. They also have 'Vias' (Links between the top and bottom copper layers) that are almost impossible to do yourself. You have to resort to soldering wires between the top and bottom tracks. Ugly!:frown2:
> ...


What he said . I think you can get 3 of the nacelle disc boards for less than $20 (with free shipping) from OSHPark.


----------



## Voyager (Dec 30, 2017)

okay. Doing myself is for curiosity really. $20 is pretty cheap!


----------



## Torgo (Apr 24, 2005)

This looks like an excellent lighting solution. Thanks so much for posting it!

I downloaded the parts list for the nacelle lighting, but I didn't see anything listed for the white, 9-pin, right-angle header mounted on the right-hand edge of the driver board:

Arduino_Logic_Board_Front by Ross the Boss, on Flickr

Does anyone have a source & part number for this and it's corresponding female connector?


----------



## RossW (Jan 12, 2000)

Torgo said:


> This looks like an excellent lighting solution. Thanks so much for posting it!
> 
> I downloaded the parts list for the nacelle lighting, but I didn't see anything listed for the white, 9-pin, right-angle header mounted on the right-hand edge of the driver board:
> 
> ...


Hi Torgo - I didn't include that part because I figured modellers would solder the wires straight to the board; I only used connectors because I had glued up my nacelle struts and didn't want to break them apart to put in more wires, so I made the board thin enough to slide into each nacelle from the back. You could do that too, or have the board inside the model/base and run the 7 wires up the nacelle struts.

To answer your question, though, here are the DigiKey part numbers for the header and housing:

WM4305-ND CONN HEADER 7POS .100 R/A TIN
WM2617-ND CONN HSNG 7POS .100 W/RAMP/RIB

Note that the prototype used for the photo had 9 pins, whereas the production version that I uploaded has 7.

HTH,
Ross


----------



## Torgo (Apr 24, 2005)

Ah- gotcha! Makes perfect sense. Do you have any photos or videos of this solution installed in a completed model? I'd love to see how it looks in context with the whole enchilada.


----------



## RossW (Jan 12, 2000)

Torgo said:


> Ah- gotcha! Makes perfect sense. Do you have any photos or videos of this solution installed in a completed model? I'd love to see how it looks in context with the whole enchilada.


My model isn’t finished yet - I’m waiting on a custom base before I can finish the painting - but I’ll certainly post updates when they happen.


----------



## Alien (Sep 5, 2001)

Just thought that I would post a quick photo.
Finally, I have installed LEDs on Ross's great round Warp Nacelle lighting PCB's. Thanks Ross :thumbsup:

I made an additional control PCB to run the LEDs and the fan motors.
I am using two microcontrollers. Probably a bit overkill, but I have a stack of these PIC 12F508 in my stash so I thought that I would use them up. Each 12F508 is configured with 5 outputs and 1 input.
Both chip inputs a linked together so I can get them to power up/down the LEDs and motors with one wire. So only three wires need to go up the nacelle pylons (+5volts, ground and control)
The 1st microcontroller fades up/down the 5 orange LEDs using one of the transistors in a ULN2003 driver chip. It also uses 4 output pins to control a micro stepper motor via a L293D H-Bridge motor driver chip. The motor slowly speeds up and slows back down to stop when the control pin is activated.
The second microcontroller blinks the 5 sets of colored LEDs, via the ULN2003. 









The camera washed out the colored LEDs, sorry! But it looks great in real life.

Just an aside. The 3mm green LEDs I used where way to bright compared to the others. I could have used a larger dropping resistor to reduce their intensity but I had soldered everything together and did not want to remove anything.
Just use some Tamiya 'Smoke' X-19 and slop it on the LED. This will reduce its intensity. The more coats, the less bright.

Alien (Slowly but surely)


----------



## RossW (Jan 12, 2000)

Alien said:


> Just thought that I would post a quick photo.
> Finally, I have installed LEDs on Ross's great round Warp Nacelle lighting PCB's. Thanks Ross :thumbsup:
> 
> I made an additional control PCB to run the LEDs and the fan motors.
> ...


 That looks great! Glad my discs were helpful. Fun fact - I started this TOS E lighting project using PIC microcontrollers and implemented the fade in/out for the main amber LEDs and the motor speed. I even had a button that would reverse the direction of the port motor since some people feel the two should spin in the same direction (some effects shots do have that), but ultimately I moved to Arduinos as it was easier to teach in demos.

I'd love to see a video of this! I had also tried steppers but the vibration (even with microstepping) was out of control.

I played around with resistor values for the LEDs quite a lot until I got the right balance, and every time I used one from a different batch (but same colour) I'd have to start again.


----------



## Alien (Sep 5, 2001)

RossW said:


> I had also tried steppers but the vibration (even with microstepping) was out of control.


Ross,

I found some little stepper motors on aliexpress.com that have a tiny gear box in them.
I can now drive the stepper motors at higher speed and the fans rotate at the correct speed. There is no vibration and no noise.. Well may be a very tiny amount, but almost inaudible noise.

I thought about having the two motors able to rotate in the same direction but to me it just looks wrong visually. It looks much better having the engines counter rotating.

I will try and post a video when I am a bit further along.

Alien


----------



## taneal1 (Jul 27, 2014)

Alien said:


> Ross,
> I found some little stepper motors on aliexpress.com that have a tiny gear box in them.
> I can now drive the stepper motors at higher speed and the fans rotate at the correct speed. There is no vibration and no noise.. Well may be a very tiny amount, but almost inaudible noise.


Alien,

Can you identify the specific motors you used? 

Thanks,

Tom


----------



## Alien (Sep 5, 2001)

Tom,

Sorry about the slow reply. I have been a bit busy
Here is a link to the stepper motors that I am using.
https://www.aliexpress.com/item/NMB-dia-15mm-5V-deceleration-Micro-motor-2-phase-4-wire-stepper-motor-Step-angle-15/32780204202.html?spm=a2g0s.9042311.0.0.27424c4dVaZU7X

Hope that this helps
Alien


----------



## RossW (Jan 12, 2000)

Alien said:


> Tom,
> 
> Sorry about the slow reply. I have been a bit busy
> Here is a link to the stepper motors that I am using.
> ...


Thanks Alien. I went to order some but the cheapest shipping option is $42. Oh well.

EDIT: if I order just 3 at a time I can get the free shipping. More than 3 and the shipping is outrageous.


----------



## Alien (Sep 5, 2001)

Ross,

I only ordered two so shipping was free for me.
$42 is indeed outrageous. Maybe OK if you order 1000.?? But if shipping is free for three, it should be free for more. I reckon that they got the shipping wrong... It happens.

I ordered some transistors to fix my bedside clock radio. I only wanted one but I was forced to order 100. But the total cost, including shipping, was US$1. I could not send a postcard to China for $1. And the aliexpress store will loose a percentage to list on the site as well as what the credit card company will take.. I don't know how they do it..

Alien


----------



## RossW (Jan 12, 2000)

RossW said:


> Thanks Alien. I went to order some but the cheapest shipping option is $42. Oh well.
> 
> EDIT: if I order just 3 at a time I can get the free shipping. More than 3 and the shipping is outrageous.


My order arrived today, and although I had to do two separate orders of 3 each all 6 arrived together. Weird.

Alien - can you please show me how you attached the spinning inner hemisphere to the stepper motor shaft?


----------



## RossW (Jan 12, 2000)

So, after years of trying to get a constant speed spinning busard domes solution for my TOS E model I've finally got one I'm happy with. I've using the geared steppers referenced by Alien and a SilentStepStick TMC2208 board which completely eliminates the "whine", and if you set the current-limiting pot down to the minimum to spin the plastic domes, there's no heat and no vibration. Plus, one board can power two steppers, and you can connect them to counter rotate - perfect!



*Arduino Code*


```
/*

Constant Speed stepper motor control using AccelStepper library



TODOs
=====

  1.  Switch to non-blocking LED blinking (e.g. https://www.arduino.cc/en/tutorial/BlinkWithoutDelay)


SilentStepStick TMC2208
=======================

https://shop.watterott.com/SilentStepStick-TMC2208-Stepper-Motor-Driver

1/2 step mode (MS1 > +5V; MS2 > GND)

Current limiter: Vref = 210mV (400mV for 2 motors)

SparkFun Rotary Encoder
=======================

https://www.sparkfun.com/products/9117


Rotary Encoder Wiring
=====================

https://bildr.org/blog/wp-content/uploads/2012/03/Rotary_Encoder_Switch_Arduino_Hookup.png


*/

/*

  IMPORTANT: COMMENT OUT THE LINE BELOW FOR PRODUCTION USE, OR WHEN POWERING BOARD
             VIA Vin PIN (i.e. when not connected go your computer via USB cable)

*/

//#define DEBUG_MODE


// Libraries
// =========
#include <AccelStepper.h>
#include <ClickEncoder.h>
#include <TimerOne.h>
#include <EEPROM.h>


// Define pins for stepper motor control, and others
#define DIR_PIN   6   // Req'd for AccelStepper
#define STEP_PIN  5   // Step on rising edge
#define EN_PIN    4   // LOW: Driver enabled. HIGH: Driver disabled
#define LED_PIN   LED_BUILTIN  // Speed adjustment indicator

// Set up accelStepper intance
AccelStepper stepper(AccelStepper::DRIVER, STEP_PIN, DIR_PIN); 

// Set up ClickEncoder instance
ClickEncoder *encoder;

// ClickEncoder Timer1 ISR
void timerIsr() {
  encoder->service();
}

// Set up stepper speed details 

// For NMB stepper with gear box reduction ratio of 1:41.66666:
//   Motor step angle 15 deg
//   Output shaft step angle 0.36 deg
//   1000 pulse output = 360 deg

float motorRPM = 660.0;  // # of steps per second (1/2 step)
float maxRPM = motorRPM*2.0;
float minRPM = motorRPM/2.0;
float adjFactor = 10.0;

// Set up variables with for ramping up during setup()
unsigned long timeStamp1;
unsigned long previousAccel = 0;
int interval = 15;     // # of milliseconds between speed increases (1/2 step)

bool motorRPMAdj = false;
unsigned long timeStamp2;
long elapsedTimeBeforeSave = 5000; // Wait 5sec after last change before saving new speed to EEPROM

int eeAddress = 0; // EEPROM address to start reading from

void setup()
{  

  // Prepare pins
  pinMode(EN_PIN, OUTPUT);
  digitalWrite(EN_PIN, HIGH);   // Disable driver in hardware

  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, LOW);   // Speed adj indicator should be off initially
  

  stepper.setMaxSpeed(maxRPM);
  stepper.setSpeed(10);         // Set to a really low value in anticipation of ramping up to
                                // motorRPM in setup()

  encoder = new ClickEncoder(A0, A1, 7, 4); // A0 = B; A1 = A; 7 = Btn; SparkFun rotary encoder has 12 indents = 4
  encoder->setAccelerationEnabled(false);
  encoder->setDoubleClickEnabled(false);
  
  Timer1.initialize(1000);
  Timer1.attachInterrupt(timerIsr);

  digitalWrite(EN_PIN, LOW);    // Enable driver in hardware

#ifdef DEBUG_MODE
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
#endif

  // Get the float data from the EEPROM at position 'eeAddress'
  float f = 0.00f;   // Variable to store data read from EEPROM.
  EEPROM.get( eeAddress, f );

#ifdef DEBUG_MODE
  Serial.print("EEPROM f val: ");
  Serial.println( f, 3 );  // This may print 'ovf, nan' if the data inside the EEPROM is not a valid float.
#endif

  if (!isnan(f)) {
    // EEPROM read yields numerical value, so set motorRPM to this if it's within min/max
    if ((f >= minRPM) && (f <= maxRPM)) {
      motorRPM = f;
    }  
  }

#ifdef DEBUG_MODE
  Serial.print("motorRPM: ");
  Serial.println(motorRPM);  // This may print 'ovf, nan' if the data inside the EEPROM is not a valid float.
#endif

  // Initial ramp up to motorRPM on startup
  while (stepper.speed() < motorRPM) {
    timeStamp1 = millis();
    if (timeStamp1 > previousAccel + interval) {
      previousAccel = timeStamp1;

      if (stepper.speed() + 2 > motorRPM) {
        stepper.setSpeed(motorRPM);
      } else {
        stepper.setSpeed(stepper.speed() + 2);
      }
    }
    
    stepper.runSpeed();
  }

}

void loop()
{  

  // Check if rotary button pressed
  ClickEncoder::Button b = encoder->getButton();
  if (b != ClickEncoder::Open) {
    
    switch (b) {
      case ClickEncoder::Released:
        // Enable speed adjustment via rotary encoder
        
        motorRPMAdj = true;             // Turn on state variable
        timeStamp2 = millis();          // Start timer to determine when ajustments are done
        
        digitalWrite(LED_PIN, HIGH);    // Turn on speed adj indicator
        
        break;
    }

  } 

  // Check if rotary encoder has changed & adjust speed accordingly
  if (motorRPMAdj == true) {
    checkEncoder();
  }

  stepper.runSpeed();

  // Save new motor RPM after appropriate elapsed time
  unsigned long currentTime = millis();

  if ( motorRPMAdj == true && ( (currentTime - timeStamp2) > elapsedTimeBeforeSave) ) {
    
//    EEPROM.put(eeAddress, motorRPM); // update EEPROM with new motorRPM

    motorRPMAdj = false;          // reset flag
    
    digitalWrite(LED_PIN, LOW);   // Turn off speed adj indicator
   
#ifdef DEBUG_MODE
    Serial.print("motorRPMAdj: ");
    Serial.println(motorRPMAdj);
    Serial.print("Saved motorRPM: ");
    Serial.println(motorRPM);
#endif
  
  }

  
}



/*
    Purpose: check if rotary encoder has been used and adjust stepper motor speed
    Parameters: none
    Returns: nothing
*/
void checkEncoder() {

  int16_t encVal = encoder->getValue(); // returns 1 for CW; -1 for CCW (dependng on A/B connectuon); 0 if untouched
  
  if (encVal != 0) {
    // Rotary encoder knob was turned left or right

    timeStamp2 = millis(); // reset timer every time the knob is turned
    
    // Update stepper speed, keeping within min/max values
    motorRPM = motorRPM + (encVal*adjFactor);
    if (motorRPM < minRPM) {
      motorRPM = minRPM;
    }
    if (motorRPM > maxRPM) {
      motorRPM = maxRPM;
    }
    
    stepper.setSpeed(motorRPM);

#ifdef DEBUG_MODE
    Serial.print("encVal: ");
    Serial.println(encVal);
    Serial.print("motorRPM: ");
    Serial.println(motorRPM);
#endif

  }

}
```


----------



## taneal1 (Jul 27, 2014)

RossW said:


> So, after years of trying to get a constant speed spinning busard domes solution for my TOS E model I've finally got one I'm happy with.
> 
> I've using the geared steppers referenced by Alien


This is GREAT news Ross, thanks for sharing! But... according to the link to the Stepper motors, they are "no longer available." :crying:
Tom


----------



## RossW (Jan 12, 2000)

taneal1 said:


> RossW said:
> 
> 
> > So, after years of trying to get a constant speed spinning busard domes solution for my TOS E model I've finally got one I'm happy with.
> ...


Try searching Aliexpress - I think I saw similar ones last month.


----------

