XRAD'S PLASMA ENGINE (Music Maker, 2.4" TFT Touch)

Please tell us which board you are using.
For CircuitPython issues, ask in the Adafruit CircuitPython forum.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
User avatar
XRAD
 
Posts: 754
Joined: Sat Nov 19, 2016 3:28 pm

XRAD'S PLASMA ENGINE (Music Maker, 2.4" TFT Touch)

Post by XRAD »

This is a continuation of the FLAMETHROWER build (admin, feel free to delete from Trinket section). I moved this out of Trinket section as It's really going to be a cool feather project. UPS a bit delayed with snow with my feather TFT touch and a few MO express boards, so I worked with a spare ILI9341 touch TFT and a teensy3.2. A few issues to get running but now I have nice slider function for three control aspects of the build.

Have a Feather Music Maker hooked up but not yet functional. Will be using interrupts as in my other project , the EYE.

Goal is to have control of PLASMA COLOR, SOUND LEVEL, and PLASMA VOLUME. I got the Adafruit class D 20 watt working great with spi volume control.

Have a 30mm ducted fan for air handling, a 15 amp esc on stepped PWM for speed control, 3s lipo, 15 amp 3s to 2s down regulator, 3 pixies, and of course the plasma generator engine to blend together.... need 12v for amp, 5v for boards and 5v w/amps for pixies

I am using UTFT.h and URTouch.h for TFT control, and you must also include the appropriate

UTFT myGLCD(ILI9341_S5P, 11, 13, 10, 8, 9); // pins for the (ILI9341_S5P, mosi,sck,cs,rst,dc)

URTouch myTouch( 6, 5, 4, 3, 2); // pins for the ILI9341 (clk, cs, mosi, miso, irq/pen)


more to come....
Attachments
IMG_2779.JPG
IMG_2779.JPG (93.02 KiB) Viewed 535 times
IMG_2786.JPG
IMG_2786.JPG (180.04 KiB) Viewed 535 times
Last edited by XRAD on Sun Dec 02, 2018 9:28 am, edited 1 time in total.

User avatar
XRAD
 
Posts: 754
Joined: Sat Nov 19, 2016 3:28 pm

Re: XRAD'S PLASMA ENGINE

Post by XRAD »

UPS made it! not sure how well this stack will do. Coding might be tricky....

2.4 tft touch Feather which has 320 x 240 density, same as the protoTFT ILI9341. Feather usable screen is about 50mm vs 58 for the protoscreen, but the nice part is that hopefully, I will not have to adjust all the pixel location code!!
Attachments
IMG_2788.JPG
IMG_2788.JPG (169.81 KiB) Viewed 528 times

User avatar
rzelko
 
Posts: 48
Joined: Wed Feb 28, 2018 9:57 pm

Re: XRAD'S PLASMA ENGINE

Post by rzelko »

Cool build, XRAD! Anxiously awaiting your experience with polling ts.touched() while the MM is playing. I don’t know, obviously, how it functions, but it’d be really helpful if you had it play a track for an extended period (shoot for a typical music track around 3 minutes) to see if it hangs up. Do you have plans to utilize the IRQ pad on the TFT? I’m having a bit of trouble understanding how to wire it up and call an ISR to possibly interrupt the MP3 playback since ts.touch() seems problematic.

The feather platform sure cleans up the wiring. I can imagine what my project would look like without the feather setup.

User avatar
XRAD
 
Posts: 754
Joined: Sat Nov 19, 2016 3:28 pm

Re: XRAD'S PLASMA ENGINE

Post by XRAD »

THX! I started my base program using UTFT and UTOUCH. Pretty easy to work with for drawing the needed screens . Only get a few font choices, small, big, and one number set. But I spent some time getting all my buttons functioning , sliders working, and screen displaying just right, and to convert over to TFT would be a PITA at this point.

I have neopixels functioning, but only when I'm in the LED color choice screen as a test. I have to rewrite my functions for the neopixels and move them into a multitasking format.

I have not gotten to the MM control section or amp volume control. Just finished mapping the touch screen buttons and starting to link then to functions for sound volume and plasma volume....

still teaching myself multiple hardware SPI and bus strategies....

User avatar
XRAD
 
Posts: 754
Joined: Sat Nov 19, 2016 3:28 pm

Re: XRAD'S PLASMA ENGINE

Post by XRAD »

still on the protoboard. Got most of the GUI stuff down. Have to add MM Feather sound and change out to adafruit feather touch screen. Just ordered an adafruit Teensy 3.x board adapter. will give that a try mounted to back of ada touch screen. The feather touch screen works great with the provided arduino examples. I do not know enough about running several pieces of hardware off one controller using SPI and all the bit formats so this could take a while....

I do like Adafruit GFX lib because it comes with more fonts and plenty of patterns and color , but the UTFT and UTOUCH are simple (like color choice and drawing round corners) and have some other good points too. I tried adding different fonts to the sketch, but did not work out...there are a whole bunch listed on the rinkydink site.. I really wanted TRONFont!!

Using the Music Maker feather, one thing I can't find is a way to play track in a HOLD like on the FX series mp3 players. I want to loop a background sound track without having to query the SD card list each time or run through an 'if statement about track stopped ' etc..

anyone have a command to do this the Music Maker ? smooth loop is what I am looking for like the FX series using button press.

The base for this comes from https://howtomechatronics.com/tutorials ... -tutorial/ and the graphics libraries from http://www.rinkydinkelectronics.com/r_fonts.php Unfortunately, lots of pop up adds on howtomechatronics, much less on rinkydink.

So the work flow is basically as follows. To get the Plasma Engine running, you have to select:

1) plasma type (which will show when you BUTTON trigger it while on the home screen)
2) sound level for speaker via MM or 20watt amp..have not decided
3) ducted fan PWM control for output air force/volume (that's why it's showing 1500-1900)

then pull trigger (it's actually a big red momentary push button) to ignite 'smoke,' turn on the fan to selected volume, play sounds at selected level, and power the pixies.....

plenty of things to work out still.....

little video of button control.
https://www.youtube.com/watch?v=NX7f9HB ... e=youtu.be
Attachments
IMG_2802.JPG
IMG_2802.JPG (123.42 KiB) Viewed 496 times

User avatar
XRAD
 
Posts: 754
Joined: Sat Nov 19, 2016 3:28 pm

Re: XRAD'S PLASMA ENGINE

Post by XRAD »

As usual, I get sidetracked easily! Decided to add a countdown visual 'timer' to the start up screen. Super easy w/out millis . Not for real life timing, but a cool visual. Also, got some other fonts working, just drop the .c file into the sketch folder. Some work, and some don't.

Code: Select all

extern uint8_t SmallFont[]; //comes w/UTFT
extern uint8_t BigFont[]; // comes w/UTFT
extern uint8_t SevenSegNumFont[]; //comes w/UTFT  , I used this one for the countdown
//extern uint8_t Arial_round_16x24[];  // font works ,  '//' out to save storage
extern uint8_t GroteskBold24x48[]; // font works, big 24x48!

Code: Select all

int countdownStart = 6;  // for the start up count down timer, have to start at 6 because only 5 'counts' down because i < 5, and I did not want to end on a 'zero'
// in setup because we only run this once, loops 5 times. I will make up some pleasant sounding Ada Music Maker English female voice to 'warn' me!

Code: Select all

void warningHomeScreen() {
  for (int i = 0  ; i < 5  ; i++) {
    myGLCD.setColor(255, 0, 0); // Sets color to white
    myGLCD.drawRoundRect (60, 68, 255, 120);
    myGLCD.drawRoundRect (50, 58, 265, 130);
    myGLCD.drawCircle (160,180,40);
    myGLCD.setFont(GroteskBold24x48);
    myGLCD.setBackColor(0, 0, 0);
    myGLCD.print("WARNING", CENTER, 70);
    countdownStart = (countdownStart - 1); 
    myGLCD.setFont(SevenSegNumFont);
    myGLCD.setColor(0, 255, 0);
    myGLCD.print(countdownStart, CENTER, 160);
    delay (500);
     myGLCD.clrScr();    
  }
}

Also: If you have not read Adafruits tutorials 1-3 on multasking the arduino, you are missing out on an excellent resource!
https://learn.adafruit.com/multi-taskin ... 1/overview
https://learn.adafruit.com/multi-taskin ... 2/overview
https://learn.adafruit.com/multi-taskin ... 3/overview

Adafruit is my favorite site for electronics not because it sells products, but it backs them up with excellent resources and tutorials so that there is really no limit to what you can design and build. Because the challenges of coding are significantly reduced, you can spend more time artfully developing designs. Although the move to Circuit Python seems to be the current wave, I hope Adafruit keeps products C++/Arduino friendly!
Attachments
IMG_2810.JPG
IMG_2810.JPG (121.37 KiB) Viewed 485 times

User avatar
XRAD
 
Posts: 754
Joined: Sat Nov 19, 2016 3:28 pm

Re: XRAD'S PLASMA ENGINE

Post by XRAD »

Well I have to say it has been a challenge getting a second SPI device functioning. I think it's probably a pin issue. I am using a teensy 3.2 for processing. I have tried the usual SPI locations, and appropriate alternates. I think it's the SS line that is causing the problem.

Also, I moved to #include <spi4teensy3.h> instead of the usual SPI.h. no issues with that.

I was able to code for the turboFan ESC speed control, the millis() control for the multifunction trigger, and cross populated the code for the music maker. The wiring takes a bit of time to decode the correct pins on the music maker and TFT/Touch going to correct pins on the Teensy. The teensy also offers distinct SPI/I/O pins, which is nice. I did get my Feather teensy adapters, nice product. will be trying that out soon.

Anyone have any input on best way to SPI two feathers? (music maker and TFT touch)
This was helpful:
https://www.circuitsathome.com/mcu/runn ... o-spi-bus/
spaghetti 'm o n s t e r' is back again.......
spaghetti 'm o n s t e r' is back again.......
IMG_2811.JPG (222.42 KiB) Viewed 445 times

User avatar
XRAD
 
Posts: 754
Joined: Sat Nov 19, 2016 3:28 pm

Re: XRAD'S PLASMA ENGINE

Post by XRAD »

Built the teensy 3x adapter. Nice feather adapter. I soldered all the teensy pins, even the ones I know I will not be using. In the arduino adafruit ILI9341 example section, I used the Adafruit touchpaint example(see code below). There is the ability to adjust and detect touch screen inputs. The touch screen is 180 degrees out in the x direction(remember, you can map into negative (-) realm as well as 0 through x, or x through y, etc..). Several pins are reconfigured for the Teensy are described in code below. The mapping of the touch screen inputs also needed to be remapped. Nothing major, and the method of adjustment is right in the sketch. Now I just have to convert my current code over to the feather....

Note: the 'long' 12mm male header pins provided for the purpose of stacking are too short. You will really need the 15mm long size, or trim down the plastic on the female stacker....

Note: when testing your screen with the Teensy mounted, as you press the touch screen, you may inadvertently close the reboot button on the back of the teensy! (it's not your program malfunctioning, it's you!)

Here are the code adjustments if you want to use a teensy w/the 2.4" feather touch TFT:

Code: Select all

/***************************************************
  This is our touchscreen painting example for the Adafruit ILI9341 Shield
  ----> http://www.adafruit.com/products/1651

  Check out the links above for our tutorials and wiring diagrams
  These displays use SPI to communicate, 4 or 5 pins are required to
  interface (RST is optional)
  Adafruit invests time and resources providing this open source code,
  please support Adafruit and open-source hardware by purchasing
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries.
  MIT license, all text above must be included in any redistribution
 ****************************************************/


#include <Adafruit_GFX.h>    // Core graphics library
#include <spi4teensy3.h>
//#include <Wire.h>      // this is needed even tho we aren't using it
#include <Adafruit_ILI9341.h>
#include <Adafruit_STMPE610.h>

// This is calibration data for the raw touch data to the screen coordinates; corrected x/y map for Teensy
#define TS_MINX 150
#define TS_MINY 130
#define TS_MAXX 3900
#define TS_MAXY 3690

// The STMPE610 uses hardware SPI on the shield, and #3 for teensy
#define STMPE_CS 3
Adafruit_STMPE610 ts = Adafruit_STMPE610(STMPE_CS);

// The display also uses hardware SPI, plus #4 & #10 for teensy
#define TFT_CS 4
#define TFT_DC 10
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);

// Size of the color selection boxes and the paintbrush size
#define BOXSIZE 40
#define BANNED 3
int oldcolor, currentcolor;

void setup(void) {
 // while (!Serial);     // used for leonardo debugging
 
  Serial.begin(9600);
  Serial.println(F("Touch Paint!"));
  
  tft.begin();

  if (!ts.begin()) {
    Serial.println("Couldn't start touchscreen controller");
    while (1);
  }
  Serial.println("Touchscreen started");
  
  tft.fillScreen(ILI9341_BLACK);
  
  // make the color selection boxes
  tft.fillRect(0, 0, BOXSIZE, BOXSIZE, ILI9341_RED);
  tft.fillRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, ILI9341_YELLOW);
  tft.fillRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, ILI9341_GREEN);
  tft.fillRect(BOXSIZE*3, 0, BOXSIZE, BOXSIZE, ILI9341_CYAN);
  tft.fillRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, ILI9341_BLUE);
  tft.fillRect(BOXSIZE*5, 0, BOXSIZE, BOXSIZE, ILI9341_MAGENTA);
 
  // select the current color 'red'
  tft.drawRect(0, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
  currentcolor = ILI9341_RED;
}


void loop()
{
  // See if there's any  touch data for us
  if (ts.bufferEmpty()) {
    return;
  }
 
  // You can also wait for a touch
  if (! ts.touched()) {
    return;
  }


  // Retrieve a point  
  TS_Point p = ts.getPoint();
  

  Serial.print("X = "); Serial.print(p.x);
  Serial.print("\tY = "); Serial.print(p.y);
  Serial.print("\tPressure = "); Serial.println(p.z);  

 
  // Scale from ~0->4000 to tft.width using the calibration #'s
  p.x = map(p.x, TS_MINX, TS_MAXX,tft.width(), 0 );   // Corrected orientation map for Teensy
  p.y = map(p.y, TS_MINY, TS_MAXY, 0, tft.height());

  
  Serial.print("("); Serial.print(p.x);
  Serial.print(", "); Serial.print(p.y);
  Serial.println(")");
 

  if (p.y < BOXSIZE) {
     oldcolor = currentcolor;

     if (p.x < BOXSIZE) { 
       currentcolor = ILI9341_RED; 
       tft.drawRect(0, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
     } else if (p.x < BOXSIZE*2) {
       currentcolor = ILI9341_YELLOW;
       tft.drawRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
     } else if (p.x < BOXSIZE*3) {
       currentcolor = ILI9341_GREEN;
       tft.drawRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
     } else if (p.x < BOXSIZE*4) {
       currentcolor = ILI9341_CYAN;
       tft.drawRect(BOXSIZE*3, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
     } else if (p.x < BOXSIZE*5) {
       currentcolor = ILI9341_BLUE;
       tft.drawRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
     } else if (p.x < BOXSIZE*6) {
       currentcolor = ILI9341_MAGENTA;
       tft.drawRect(BOXSIZE*5, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
     }

     if (oldcolor != currentcolor) {
        if (oldcolor == ILI9341_RED) 
          tft.fillRect(0, 0, BOXSIZE, BOXSIZE, ILI9341_RED);
        if (oldcolor == ILI9341_YELLOW) 
          tft.fillRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, ILI9341_YELLOW);
        if (oldcolor == ILI9341_GREEN) 
          tft.fillRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, ILI9341_GREEN);
        if (oldcolor == ILI9341_CYAN) 
          tft.fillRect(BOXSIZE*3, 0, BOXSIZE, BOXSIZE, ILI9341_CYAN);
        if (oldcolor == ILI9341_BLUE) 
          tft.fillRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, ILI9341_BLUE);
        if (oldcolor == ILI9341_MAGENTA) 
          tft.fillRect(BOXSIZE*5, 0, BOXSIZE, BOXSIZE, ILI9341_MAGENTA);
     }
  }
  if (((p.y-BANNED) > BOXSIZE) && ((p.y+BANNED) < tft.height())) {
    tft.fillCircle(p.x, p.y, BANNED, currentcolor);
  }
}
Attachments
IMG_2812.JPG
IMG_2812.JPG (150.11 KiB) Viewed 439 times
IMG_2814.JPG
IMG_2814.JPG (134.44 KiB) Viewed 439 times

User avatar
XRAD
 
Posts: 754
Joined: Sat Nov 19, 2016 3:28 pm

Re: XRAD'S PLASMA ENGINE

Post by XRAD »

Got a bit further... I relabeled the pins on the Music Maker sketch for Teensy feather. Nothing.... tried some other pins..nothing. Removed the teensy/MM feather combo from the TFT mount and everything works fine. So obviously some shared pins that should not be shared...

Anyone with correct way to stack several SPI feathers??? Particularly the TFT/touch && processor board (in middle) && Music Maker

This is possibly my issue:
"SCK/MOSI/MISO - this should be your main SPI bus. 3.3V logic. If you share these with devices on the main featherwing, keep the CS pin from being exposed so that you don't have SPI bus contentions." (from the Feather overview specifications)

Without the CS pin for either the TFT or the MM, I am pretty sure they will not function.....tried re-designating these as well (Teensy has several CS capable pins, which is reason I am using a Teensy as the central processor). Did not work.....

here is the code I modified slightly to work w/teensy 3x feather:

Code: Select all

/***************************************************
  This is an example for the Adafruit VS1053 Codec Breakout

  Designed specifically to work with the Adafruit VS1053 Codec Breakout
  ----> https://www.adafruit.com/products/1381

  Adafruit invests time and resources providing this open source code,
  please support Adafruit and open-source hardware by purchasing
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries.
  BSD license, all text above must be included in any redistribution
 ****************************************************/

// include SPI, MP3 and SD libraries
#include <spi4teensy3.h>
#include <Adafruit_VS1053.h>
#include <SD.h>

  
// These are the pins used for the music maker shield
#define VS1053_RESET  -1      // VS1053 reset pin (unused!)
#define VS1053_CS      3      // VS1053 chip select pin (output)
#define VS1053_DCS    10     // VS1053 Data/command select pin (output)
#define CARDCS         8
#define VS1053_DREQ    4
 

 Adafruit_VS1053_FilePlayer musicPlayer =
  Adafruit_VS1053_FilePlayer(VS1053_RESET, VS1053_CS, VS1053_DCS, VS1053_DREQ, CARDCS);
 


void setup() {
  Serial.begin(9600);
  Serial.println("Adafruit VS1053 Library Test");

  // initialise the music player
  if (! musicPlayer.begin()) { // initialise the music player
    Serial.println(F("Couldn't find VS1053, do you have the right pins defined?"));
    while (1);
  }
  Serial.println(F("VS1053 found"));

  musicPlayer.sineTest(0x44, 500);    // Make a tone to indicate VS1053 is working

  if (!SD.begin(CARDCS)) {
    Serial.println(F("SD failed, or not present"));
    while (1);  // don't do anything more
  }
  Serial.println("SD OK!");

  // list files
  printDirectory(SD.open("/"), 0);

  // Set volume for left, right channels. lower numbers == louder volume!
  musicPlayer.setVolume(20, 20);

  /***** Two interrupt options! *******/
  // This option uses timer0, this means timer1 & t2 are not required
  // (so you can use 'em for Servos, etc) BUT millis() can lose time
  // since we're hitchhiking on top of the millis() tracker
  //musicPlayer.useInterrupt(VS1053_FILEPLAYER_TIMER0_INT);

  // This option uses a pin interrupt. No timers required! But DREQ
  // must be on an interrupt pin. For Uno/Duemilanove/Diecimilla
  // that's Digital #2 or #3
  // See http://arduino.cc/en/Reference/attachInterrupt for other pins
  // *** This method is preferred
  if (! musicPlayer.useInterrupt(VS1053_FILEPLAYER_PIN_INT))
    Serial.println(F("DREQ pin is not an interrupt pin"));
}

void loop() {
  // Alternately, we can just play an entire file at once
  // This doesn't happen in the background, instead, the entire
  // file is played and the program will continue when it's done!
  musicPlayer.playFullFile("track001.ogg");

  // Start playing a file, then we can do stuff while waiting for it to finish
  if (! musicPlayer.startPlayingFile("roar.wav")) {
    Serial.println("Could not open file track001.wav");
    while (1);
  }
  Serial.println(F("Started playing"));

  while (musicPlayer.playingMusic) {
    // file is now playing in the 'background' so now's a good time
    // to do something else like handling LEDs or buttons :)
    Serial.print(".");
    delay(1000);
  }
  Serial.println("Done playing music");
}


/// File listing helper
void printDirectory(File dir, int numTabs) {
  while (true) {

    File entry =  dir.openNextFile();
    if (! entry) {
      // no more files
      //Serial.println("**nomorefiles**");
      break;
    }
    for (uint8_t i = 0; i < numTabs; i++) {
      Serial.print('\t');
    }
    Serial.print(entry.name());
    if (entry.isDirectory()) {
      Serial.println("/");
      printDirectory(entry, numTabs + 1);
    } else {
      // files have sizes, directories do not
      Serial.print("\t\t");
      Serial.println(entry.size(), DEC);
    }
    entry.close();
  }
}

Attachments
roar play.JPG
roar play.JPG (84.62 KiB) Viewed 435 times
IMG_2817.JPG
IMG_2817.JPG (174.87 KiB) Viewed 435 times

User avatar
XRAD
 
Posts: 754
Joined: Sat Nov 19, 2016 3:28 pm

Re: XRAD'S PLASMA ENGINE

Post by XRAD »

Time to show some code! Unfortunately, even after hours of trying, I could not get the Music Maker Feather AND the TFT touch to work at same time. It did actually work for about 5 min, then I started getting the old modem sound out of the speaker. I could always get the MM recognized using miso,mosi, clk on pins 11,12,13 when 18 DREQ, 19 DCS, 20 SDCS, and 21 CS. Sometimes I would get the file list, and sometimes not. I did try all the listed CS pins and tx rx pins and every other pin variant I could think of on teensy. I think there is a pin/clk/cs conflict when TFT/Touch is hooked up, perhaps behind the scenes in the lib, but it is beyond me right now.

On the positive side, the MM works fine on my teensy feather without a TFT/Touch hooked up. When I did have TFT/Touch hooked up, I was able to play sounds AND do my pixel show AND change TFT pages without interruption, which was cool. But short lived .......

So.... I moved back to a spare FXMini and the Adafruit 20 watt amp! NICE LOUD AMP!! put 12v to it and go deaf. I am using I2C to control the volume. It is mapped from a slider position on GUI page 2. There is no checking of I2C, so I put a 10ms delay on the line before Wire.endTransmission(MAX9744_I2CADDR); Line 620 or so...

I only have 5 sounds for this build, so I will be using the FXMini. I love the FX series. Super easy to load files. I did try serial FXMini control, but honestly, it was more lines of code and does not seem to easily do the HOLD.L that I want. So back to 3904's...

Note: You will need certain TFT libraries http://www.rinkydinkelectronics.com/library.php?id=51 and download Grotesque font from http://www.rinkydinkelectronics.com/r_fonts.php. Note how UTFT and Touch are defined in objects.

Some of the display code could have been shortened into arrays or structs, but currently, it's easy to understand.....

Presently, I have:
1) funtioning TFT
2) funtioning TFT Touch
3) 4 different Neopixel show w/out delays
4) 20watts of sound
5) GUI PWM control of a turbofan for plasma volume and force
6) sliding GUI volume control of 20 watt amp
7) Neopixel/sound/plasma volume settings remain in place when going back to home screen
8) 'countdown' timer on start-up
9) timer without delay for burner shutoff (runs for 5 sec, then off for 3 if you hold the trigger)
10) neopixels only 'show' when burner is active

If someone has some multi feather serial code using tft touch and music maker, please share. THX


Code: Select all

/* *****XRAD'S PLASMA ENGINE **********
 *  Another frankencode for one of my projects. Some of the code comes from
 *  Adafruit tutorials:
 *  https://learn.adafruit.com/adafruit-2-4-tft-touch-screen-featherwing/resistive-touch-screen
 *  https://learn.adafruit.com/adafruit-20w-stereo-audio-amplifier-class-d-max9744/overview
 *  and some from:
 *  https://howtomechatronics.com/tutorials/arduino/arduino-tft-lcd-touch-screen-tutorial/
 *  The rest I just imagined or cobbled together from my older projects.......
 *  I am using ILI9341 TFT Touch, simple I2C control of volume mapped to the MAX9774
 *  and  Teensy 3.2 as main processor.
 */

#include <Wire.h>
#include <SD.h>
#include <Servo.h>
#include <FastLED.h>
#include <UTFT.h>
#include <URTouch.h>

//define some basic Teensy pins
#define PLASMABUTTON  22  //trigger button to fire plasma pixies ONLY when on home screen
#define PIN          16 //Led output
#define NUMPIXELS      3
#define DELAYVAL      20 // for LED functions 

// define the pins used on Teensy 3x to FX wav
#define MAX9744_I2CADDR 0x4B
//  MAX9744_SDA to  18   defined in lib
//  MAX9744_SCL to 19    defined in lib
//  MAX9744 Vi2C to 3.3v on Teensy

//==== Declare a bunch of stuff ========

int plasmaButtonState = LOW;
unsigned long plasmaButtonTimer = 8000;  //off timer starts same time as 'on' timer
unsigned long plasmaBurnerTimer = 5000;  // max on timer, don't melt anything
unsigned long startMillis;
unsigned long currentMillis; 

extern uint8_t SmallFont[]; //comes w/UTFT
extern uint8_t BigFont[]; // comes w/UTFT
extern uint8_t SevenSegNumFont[]; //comes w/UTFT
extern uint8_t GroteskBold24x48[]; // font works

uint32_t now = 0; // for neopix display
uint8_t  mode = 0; // for neopix display
int selectLED;  // for neopix display type
int stateLED = 0;

int x, y;  // for touch screen position

char currentPage;  // current TFT page

int xR = 38;  //for sound level control slider min 


//====== turboFan  ====
int turboVolumeRange ;
int iV = 0; // 0-9 for display on plasma volume bottom right start:0
const int turboMin = 100; //no throttle
const int turboMax = 140; //full throttle
int turboStartPos = 100; // intial servo position
#define servoTurbo 23  //PWM pin out for turboPWM 

//======
int countdownStart = 6;  // for the start up count down timer, have to start at 6 because only 5 counts down

//==== Creating Some Objects

UTFT myGLCD(ILI9341_S5P, 7,  14,  10,   8,   9); // (ILI9341_S5P, MOSI, SCK, CS, RST,DC)
URTouch  myTouch( 6, 5, 4, 3, 2); // ( CLK, TCS, MOSI, MISO, IRQ(PEN))
CRGB leds[NUMPIXELS];
Servo servo1; // for turbofan


//=================================
//============= setup =============
//=================================

void setup() {
  startMillis = millis();

  Serial.begin(9600);

  Wire.begin();

  myGLCD.InitLCD();
  myGLCD.clrScr();
  myTouch.InitTouch();
  myTouch.setPrecision(PREC_MEDIUM);

  servo1.attach(servoTurbo);
  servo1.write(turboStartPos);
  delay(100);

  FastLED.addLeds<NEOPIXEL, PIN>(leds, NUMPIXELS);
  pinMode(PIN, OUTPUT);
  pinMode(PLASMABUTTON, INPUT_PULLDOWN);

  warningHomeScreen();
  drawHomeScreen();  // Draws the Home Screen
  currentPage = '0'; //  Home Screen '0' as baseline
}

//========================================
//============= Main Loop ================
//========================================

void loop() {

  currentMillis = millis();

  // Home Page button press contol

  if (currentPage == '0') {
    
    if (myTouch.dataAvailable()) {
      myTouch.read();
      x = myTouch.getX(); // X coordinate where the screen has been pressed
      y = myTouch.getY(); // Y coordinates where the screen has been pressed


      //   press the Plasma Color Button
      if ((x >= 35) && (x <= 285) && (y >= 90) && (y <= 130)) {
        drawFrame(35, 90, 285, 130); // Custom Function -Highlights button edge when pressed
        currentPage = '1'; // Indicates that we are at page '1'
        myGLCD.clrScr(); // Clears the screen
        drawPlasmaControl(); // It is called once and draws the first page.
      }

      //   press the Sound Level Button
      if ((x >= 35) && (x <= 285) && (y >= 140) && (y <= 180)) {
        drawFrame(35, 140, 285, 180);
        currentPage = '2';
        myGLCD.clrScr();
        drawSoundControl();
      }

      //   press the Plasma Volume Button
      if ((x >= 35) && (x <= 285) && (y >= 190) && (y <= 230)) {
        drawFrame(35, 190, 285, 230);
        currentPage = '3';
        myGLCD.clrScr();
        //myGLCD.setColor(114, 198, 206); MAkes whole screen this color gray
        //myGLCD.fillRect(0, 0, 319, 239);
        drawPlasmaVolume();
      }
    }
  }

  // Page 1: Plasma Color  button press control
  if (currentPage == '1') {
    neopixelShow();

    if (myTouch.dataAvailable()) {
      myTouch.read();
      x = myTouch.getX();
      y = myTouch.getY();

      // If we press the RASMA Button
      if ((x >= 10) && (x <= 150) && (y >= 115) && (y <= 163)) {
        drawFrame(10, 115, 150, 163); // Custom Function -Highlighs the buttons when it's pressed
        selectLED = '0';
      }

      // If we press the BLASMA Button
      if ((x >= 170) && (x <= 310) && (y >= 115) && (y <= 163)) {
        drawFrame(170, 115, 310, 163); // Custom Function -Highlighs the buttons when it's pressed
        selectLED = '1';
      }

      // If we press the GRASMA Button
      if ((x >= 10) && (x <= 150) && (y >= 173) && (y <= 221)) {
        drawFrame(10, 173, 150, 221); // Custom Function -Highlighs the buttons when it's pressed
        selectLED = '2';
      }

      // If we press the SPASMA Button
      if ((x >= 170) && (x <= 310) && (y >= 173) && (y <= 221)) {
        drawFrame(170, 173, 310, 221); // Custom Function -Highlights the buttons when it's pressed
        selectLED = '3';
      }


      // Back Button control
      if ((x >= 10) && (x <= 60) && (y >= 10) && (y <= 36)) {
        drawFrame(10, 10, 60, 36);
        currentPage = '0'; // Indicates we are at home screen
        myGLCD.clrScr();
        drawHomeScreen(); // Draws the home screen
        //selectLED = selectLED;
      }
    }
  }

  // Page 2: Sound level  button press contol
  if (currentPage == '2') {

    setSoundLevel();

    if (myTouch.dataAvailable()) {
      myTouch.read();
      x = myTouch.getX();
      y = myTouch.getY();

      //Back button
      if ((x >= 10) && (x <= 60) && (y >= 10) && (y <= 36)) {
        drawFrame(10, 10, 60, 36);
        currentPage = '0';
        myGLCD.clrScr();
        drawHomeScreen();

      }
    }
  }

  //Page Three: PlasmaVolume button press contol

  if (currentPage == '3') {

    setPlasmaVolume();

    myGLCD.setColor(0, 255, 0);
    myGLCD.setFont(SevenSegNumFont);
    myGLCD.setBackColor(200, 0, 200);
    myGLCD.print(iV, 193, 177);

    if (myTouch.dataAvailable()) {
      myTouch.read();
      x = myTouch.getX();
      y = myTouch.getY();


      //Back button
      if ((x >= 10) && (x <= 60) && (y >= 10) && (y <= 36)) {
        drawFrame(10, 10, 60, 36);
        currentPage = '0';
        myGLCD.clrScr();
        drawHomeScreen();
      }
    }
  }

  plasmaButtonState = digitalRead(PLASMABUTTON);

  if  ((plasmaButtonState == HIGH) && (currentPage == '0' ) && (currentMillis - startMillis < plasmaButtonTimer)) {
    if  (currentMillis - startMillis < plasmaBurnerTimer) {
      neopixelShow();
/*  // If I ever get serial control of a wav player, 'playTrack(x)' will go here
      if (selectLED == '0' ) {
      }
      if (selectLED == '1' ) {
      }
      if (selectLED == '2' ) {
      }
      if (selectLED == '3' ) {
     }
*/
    }
  }


  else  {
    startMillis = currentMillis;
    if ((plasmaButtonState == LOW) && (currentPage == '0' ))  {


      delay(10);
    }
  }
}


//=============================================
//=========== Custom Draw Funtions ============
//=============================================

// home screen warning runs once on setup and counts down 5 to 0

void warningHomeScreen() {
  for (int i = 0  ; i < 5  ; i++) {
    myGLCD.setColor(255, 0, 0); // Sets color to white
    myGLCD.drawRoundRect (60, 28, 255, 80);
    myGLCD.drawRoundRect (50, 18, 265, 90);
    myGLCD.drawCircle (160, 190, 40);
    myGLCD.setFont(GroteskBold24x48);
    myGLCD.setBackColor(0, 0, 0);
    myGLCD.print("WARNING", CENTER, 30);
    myGLCD.setFont(SmallFont);
    myGLCD.setColor(255, 255, 255);
    myGLCD.print("PLASMA ENGINE IGNITION IN:", CENTER, 115);
    countdownStart = (countdownStart - 1);
    myGLCD.setFont(SevenSegNumFont);
    myGLCD.setColor(0, 255, 0);
    myGLCD.print(countdownStart, CENTER, 165);
    delay (300);
    myGLCD.clrScr();
  }
}

// draw Home Screen

void drawHomeScreen() {
  myGLCD.setBackColor(0, 0, 0); // Sets the background color of the area where the text will be printed to black
  myGLCD.setColor(255, 255, 255);
  drawFrame(1, 1, 318, 238);
  myGLCD.setColor(255, 255, 255); // Sets color to white
  myGLCD.setFont(BigFont); // Sets font to big
  myGLCD.print("PLASMA ENGINE", CENTER, 10); // Prints the string on the screen
  myGLCD.setColor(255, 255, 255); // Sets color to white
  myGLCD.setFont(SmallFont); // Sets the font to small
  myGLCD.print("WARNING: MOSTLY DANGEROUS", CENTER, 35); // Prints the string  myGLCD.setFont(DotMatrix_M_Slash);
  myGLCD.print("TOASTER SETTINGS MUST BE", CENTER, 50);
  myGLCD.print("SELECTED BEFORE OPERATING", CENTER, 65);

  // Button - PLASMA COLOR
  myGLCD.setColor(228, 7, 215); // Sets green color
  myGLCD.fillRoundRect (35, 90, 285, 130); // Draws filled rounded rectangle
  myGLCD.setColor(255, 255, 255); // Sets color to white
  myGLCD.drawRoundRect (35, 90, 285, 130); // Draws rounded rectangle without a fill, so the overall appearance of the button looks like it has a frame
  myGLCD.setFont(BigFont); // Sets the font to big
  myGLCD.setBackColor(228, 7, 215); // Sets the background color of the area where the text will be printed to green, same as the button
  myGLCD.print("PLASMA COLOR", CENTER, 102); // Prints the string

  // Button - SOUND LEVEL
  myGLCD.setColor(200, 200, 0);
  myGLCD.fillRoundRect (35, 140, 285, 180);
  myGLCD.setColor(255, 255, 255);
  myGLCD.drawRoundRect (35, 140, 285, 180);
  myGLCD.setFont(BigFont);
  myGLCD.setBackColor(200, 200, 0);
  myGLCD.print("SOUND LEVEL", CENTER, 152);

  // Button - PLASMA VOLUME
  myGLCD.setColor(40, 200, 100);
  myGLCD.fillRoundRect (35, 190, 285, 230);
  myGLCD.setColor(255, 255, 255);
  myGLCD.drawRoundRect (35, 190, 285, 230);
  myGLCD.setFont(BigFont);
  myGLCD.setBackColor(40, 200, 100);
  myGLCD.print("PLASMA VOLUME", CENTER, 202);
}

// Highlights all GUI button edges when pressed

void drawFrame(int x1, int y1, int x2, int y2) {
  myGLCD.setColor(255, 0, 0);
  myGLCD.drawRoundRect (x1, y1, x2, y2);
  while (myTouch.dataAvailable())
    myTouch.read();
  myGLCD.setColor(255, 255, 255);
  myGLCD.drawRoundRect (x1, y1, x2, y2);
}

//===== DRAW PAGE'S 1,2,3 SIMPLE GUI's=========

// drawPlasmControl Page

void drawPlasmaControl() {
  myGLCD.setColor(100, 155, 203);
  myGLCD.fillRoundRect (10, 10, 60, 36);
  myGLCD.setColor(255, 255, 255);
  myGLCD.drawRoundRect (10, 10, 60, 36);
  myGLCD.setFont(BigFont);
  myGLCD.setBackColor(100, 155, 203);
  myGLCD.print("<-", 18, 15);
  myGLCD.setBackColor(0, 0, 0);
  myGLCD.setFont(SmallFont);
  myGLCD.print("Back to Main Menu", 70, 18);
  myGLCD.setFont(BigFont);

  myGLCD.print("PLASMA COLOR", CENTER, 50);
  myGLCD.print("Select for Color", CENTER, 76);
  myGLCD.setBackColor(0, 0, 0);
  myGLCD.setColor(255, 255, 255);


  myGLCD.setColor(200, 0, 0);
  myGLCD.fillRoundRect (10, 115, 150, 163);
  myGLCD.setColor(225, 255, 255);
  myGLCD.drawRoundRect (10, 115, 150, 163);
  myGLCD.setBackColor(200, 0, 0);
  myGLCD.setColor(255, 255, 255);
  myGLCD.print("RASMA", 40, 130);

  myGLCD.setColor(0, 0, 200);
  myGLCD.fillRoundRect (170, 115, 310, 163);
  myGLCD.setColor(225, 255, 255);
  myGLCD.drawRoundRect (170, 115, 310, 163);
  myGLCD.setBackColor(0, 0, 200);
  myGLCD.setColor(255, 255, 255);
  myGLCD.print("BLASMA", 190, 130);

  myGLCD.setColor(0, 200, 0);
  myGLCD.fillRoundRect (10, 173, 150, 221);
  myGLCD.setColor(255, 255, 255);
  myGLCD.drawRoundRect (10, 173, 150, 221);
  myGLCD.setBackColor(0, 200, 0);
  myGLCD.setColor(255, 255, 255);
  myGLCD.print("GRASMA", 30, 190);

  myGLCD.setColor(200, 0, 200);
  myGLCD.fillRoundRect (170, 173, 310, 221);
  myGLCD.setColor(225, 255, 255);
  myGLCD.drawRoundRect (170, 173, 310, 221);
  myGLCD.setBackColor(200, 0, 200);
  myGLCD.setColor(255, 255, 255);
  myGLCD.print("SPASMA", 190, 190);
}


//drawSoundScreen Page

void drawSoundControl() {

  myGLCD.setColor(100, 155, 203);
  myGLCD.fillRoundRect (10, 10, 60, 36);
  myGLCD.setColor(255, 255, 255);
  myGLCD.drawRoundRect (10, 10, 60, 36);
  myGLCD.setFont(BigFont);
  myGLCD.setBackColor(100, 155, 203);
  myGLCD.print("<-", 18, 15);
  myGLCD.setBackColor(0, 0, 0);
  myGLCD.setFont(SmallFont);
  myGLCD.print("Back to Main Menu", 70, 18);

  myGLCD.setFont(BigFont);
  myGLCD.print("SOUND LEVEL CONTROL:", 10, 75);
  myGLCD.print("V", 10, 135);

  myGLCD.setColor(255, 255, 255);
  myGLCD.drawRect(30, 130, 310, 160); // R - Slider

  //volume box bottom right
  myGLCD.setColor(200, 0, 200);
  myGLCD.fillRoundRect (170, 173, 250, 230);
  myGLCD.setColor(225, 255, 255);
  myGLCD.drawRoundRect (170, 173, 250, 230);
  myGLCD.setBackColor(200, 0, 200);

  //volume level directions
  myGLCD.setBackColor(0, 0, 0);
  myGLCD.setFont(BigFont);
  myGLCD.setColor(225, 255, 255);
  myGLCD.print("TOUCH FOR", 10, 180);
  myGLCD.print("CURRENT V", 10, 200);
}


// Draw Plasa Volume Page

void drawPlasmaVolume() {

  myGLCD.setColor(100, 155, 203);
  myGLCD.fillRoundRect (10, 10, 60, 36);
  myGLCD.setColor(255, 255, 255);
  myGLCD.drawRoundRect (10, 10, 60, 36);
  myGLCD.setFont(BigFont);
  myGLCD.setBackColor(100, 155, 203);
  myGLCD.print("<-", 18, 15);
  myGLCD.setBackColor(0, 0, 0);
  myGLCD.setFont(SmallFont);
  myGLCD.print("Back to Main Menu", 70, 18);

  myGLCD.setFont(BigFont);
  myGLCD.print("PLASMA VOLUME GUI", CENTER, 50);
  myGLCD.setFont(SmallFont);
  myGLCD.print("Adjust for plasma output volume", CENTER, 70);
  myGLCD.print("and force by controlling ducted fan", CENTER, 80);


  myGLCD.setColor(0, 0, 200);
  myGLCD.fillRoundRect (10, 115, 150, 163);
  myGLCD.setColor(225, 255, 255);
  myGLCD.drawRoundRect (10, 115, 150, 163);
  myGLCD.setBackColor(0, 0, 200);
  myGLCD.setColor(255, 255, 255);
  myGLCD.setFont(BigFont);
  myGLCD.print("DECREASE", 20, 130);

  myGLCD.setColor(200, 0, 0);
  myGLCD.fillRoundRect (170, 115, 310, 163);
  myGLCD.setColor(225, 255, 255);
  myGLCD.drawRoundRect (170, 115, 310, 163);
  myGLCD.setBackColor(200, 0, 0);
  myGLCD.setColor(255, 255, 255);
  myGLCD.print("INCREASE", 180, 130);

  //Plasma volume  box bottom right
  myGLCD.setColor(200, 0, 200);
  myGLCD.fillRoundRect (170, 173, 250, 230);
  myGLCD.setColor(225, 255, 255);
  myGLCD.drawRoundRect (170, 173, 250, 230);
  myGLCD.setBackColor(200, 0, 200);

  //Plasma volume directions
  myGLCD.setBackColor(0, 0, 0);
  myGLCD.setFont(BigFont);
  myGLCD.setColor(225, 255, 255);
  myGLCD.print("CURRENT", 20, 180);
  myGLCD.print("PLASMA", 25, 200);
  myGLCD.print("VOLUME", 23, 220);
}


//=================================================
//====== Custom Touch Control functions ===========
//=================================================

//======= Sound Level Touch Settings ======

void setSoundLevel() {
  if (myTouch.dataAvailable()) {
    myTouch.read();
    x = myTouch.getX();
    y = myTouch.getY();
    // Area of the Red color slider
    if ( (y >= 130) && (y <= 160)) {
      xR = x; // Stores the X value where the screen has been pressed in to variable xR
      if (xR <= 40) { // Confines the area of the slider to be above 38 pixels
        xR = 40;
      }
      if (xR >= 300) { /// Confines the area of the slider to be under 310 pixels
        xR = 300;
      }
    }

    // Maps the values of the X - Axis from 38 to 0 and 310 to 50 for volume settings
    uint16_t xRC = map(xR, 40, 300, 10, 60);  // you can set 'out' it to 0, 40 if you want less volume and range


    Serial.print("Setting volume to ");
    Serial.println(xRC);
    Wire.beginTransmission(MAX9744_I2CADDR);
    Wire.write(xRC);
    delay(10);
    Wire.endTransmission(MAX9744_I2CADDR);

    // Draws the positioner
    myGLCD.setColor(0, 255, 0);
    myGLCD.fillRect(xR, 135, (xR + 4), 155); // Positioner
    myGLCD.setColor(255, 0, 0);
    myGLCD.fillRect(31, 135, (xR - 1), 155);
    myGLCD.setColor(0, 0, 0);
    myGLCD.fillRect((xR + 5), 135, 309, 155);

    myGLCD.setBackColor(200, 0, 200);
    myGLCD.setFont(BigFont);
    myGLCD.setColor(255, 255, 255);
    myGLCD.print(xRC, 190, 195);
    // Serial.println( xRC);
    // setvolume(xRC);
  }
}


//======Plasma Volume touch settings ============


void setPlasmaVolume() {

  int turboPWM = map(iV, 0, 9, turboMin, turboMax);
  turboVolumeRange = iV;

  if (myTouch.dataAvailable()) {
    myTouch.read();
    x = myTouch.getX();
    y = myTouch.getY();


    // If we press the DECREASE Button

    if ((x >= 10) && (x <= 150) && (y >= 115) && (y <= 163)) {
      drawFrame(10, 115, 150, 163);
      if ((iV >= 0) && (iV <= 9)) {
        iV = (iV - 1);
        if (iV <= 0) {
          iV = 0;
        }
      }
    }


    // If we press the INCREASE Button

    if ((x >= 170) && (x <= 310) && (y >= 115) && (y <= 163)) {
      drawFrame(170, 115, 310, 163);
      if ((iV >=  0) && (iV <= 9)) {
        iV = (iV + 1);
        if (iV >= 9) {
          iV = 9;
        }
      }
    }

    myGLCD.setBackColor(200, 0, 200);
    myGLCD.setColor(0, 255, 0);
    myGLCD.setFont(SevenSegNumFont);
    myGLCD.print(iV, 193, 177);

    switch (turboVolumeRange) {

      case 0:
        myGLCD.setColor(0, 0  , 255);
        myGLCD.fillCircle (280, 200, 20);
        servo1.write( turboPWM );

        if (iV <= 0) {
          myGLCD.setBackColor(0, 0  , 255);
          myGLCD.setFont(SmallFont);
          myGLCD.setColor(255, 255, 255);
          myGLCD.print("OFF", 270, 195);
        }
        break;

      case 1:
        myGLCD.setColor(0, 0  , 255);
        myGLCD.fillCircle (280, 200, 20);
        servo1.write( turboPWM );
        break;

      case 2:
        myGLCD.setColor(0, 100  , 200);
        myGLCD.fillCircle (280, 200, 20);
        servo1.write( turboPWM );
        break;

      case 3:
        myGLCD.setColor(0, 150 , 0);
        myGLCD.fillCircle (280, 200, 20);
        servo1.write( turboPWM );
        break;

      case 4:
        myGLCD.setColor(0, 255  , 0);
        myGLCD.fillCircle (280, 200, 20);
        servo1.write( turboPWM );
        break;

      case 5:
        myGLCD.setColor(0, 255  , 0);
        myGLCD.fillCircle (280, 200, 20);
        servo1.write( turboPWM );
        break;

      case 6:
        myGLCD.setColor(100, 150  , 0);
        myGLCD.fillCircle (280, 200, 20);
        servo1.write( turboPWM );
        break;

      case 7:
        myGLCD.setColor(200, 0  , 0);
        myGLCD.fillCircle (280, 200, 20);
        servo1.write( turboPWM );
        break;

      case 8:
        myGLCD.setColor(255, 0  , 0);
        myGLCD.fillCircle (280, 200, 20);
        servo1.write( turboPWM );
        break;

      case 9:
        myGLCD.setColor(255, 0  , 0);
        myGLCD.fillCircle (280, 200, 20);
        servo1.write( turboPWM );

        if (iV >= 9) {
          myGLCD.setBackColor(255, 0  , 0);
          myGLCD.setFont(SmallFont);
          myGLCD.setColor(255, 255, 255);
          myGLCD.print("MAX", 270, 195);
        }
        break;
    }
  }
}


//=================================================
//======== special LED Plasma functions  ==========
//=================================================


void neopixelShow() {
  if (selectLED == '0' ) {
    redFire(now, leds, NUMPIXELS);
    FastLED.show();
    //Serial.println ("default LED display");
    delay(DELAYVAL);
    now++;
  }

  if (selectLED == '1') {
    blueFire(now, leds, NUMPIXELS);
    FastLED.show();
    delay(DELAYVAL);
    now++;
  }

  if (selectLED == '2') {
    greenFire(now, leds, NUMPIXELS);
    FastLED.show();
    delay(DELAYVAL);
    now++;
  }

  if (selectLED == '3') {
    sparkleFire();
  }
}



void redFire(uint32_t now, CRGB * leds, int numpixels) {
  CRGB red(255, 0, 0);
  CRGB orange( 255, 150, 0);
  for (int i = 0; i < NUMPIXELS; i++) {
    CRGB dest = blend(  red, orange, inoise8((now) * 17, i * 60));
    leds[i] = dest;
  }
  fadeToBlackBy(leds, NUMPIXELS, map(inoise8(now * 50), 0, 50, 50, 20));
}


void blueFire(uint32_t now, CRGB * leds, int numpixels) {
  CRGB blue(0, 0, 255);
  CRGB lightBlue( 0, 255, 255);
  for (int i = 0; i < NUMPIXELS; i++) {
    CRGB dest = blend(  blue, lightBlue, inoise8((now) * 17, i * 60));
    leds[i] = dest;
  }
  fadeToBlackBy(leds, NUMPIXELS, map(inoise8(now * 50), 0, 50, 50, 20));
}

void greenFire(uint32_t now, CRGB * leds, int numpixels) {
  CRGB green(0, 150, 0);
  CRGB lightGreen( 153, 250, 51);
  for (int i = 0; i < NUMPIXELS; i++) {
    CRGB dest = blend(  green, lightGreen, inoise8((now) * 17, i * 60));
    leds[i] = dest;
  }
  fadeToBlackBy(leds, NUMPIXELS, map(inoise8(now * 50), 0, 50, 50, 20));
}


void sparkleFire() {
  leds[random(3)] = CRGB::White;
  leds[random(3)] = CRGB::Blue;
  leds[random(3)] = CRGB::Black;
  leds[random(3)] = CRGB::Green;
  leds[random(3)] = CRGB::Yellow;
  leds[random(3)] = CRGB::Red;
  FastLED.setBrightness(175);
  FastLED.show();
  delay(8);
}

// Not used yet but could be.....
void blackFire() {
  for (int i = 0; i < 1; i++) {
    leds[random(3)] = CRGB::Black;
    FastLED.setBrightness(0);
    FastLED.show();
  }
}


User avatar
rzelko
 
Posts: 48
Joined: Wed Feb 28, 2018 9:57 pm

Re: XRAD'S PLASMA ENGINE

Post by rzelko »

XRAD, This attached image is the way that I was shown to work around conflicts between the MM and the TFT FeatherWing. It worked well for me because I am using the M0 WiFi and it has plenty of GPIOs. The main problem I am still fighting is that the MM doesn't allow me to poll for ts.touched() without locking up the whole setup. I am still waiting for Adafruit tech support to weigh in on this topic.

If you have a moment, can you help me figure out how to work with the IRQ pad on the TFT. I am really struggling to figure out how to get it hooked up and setup as an external interrupt. I know that the STMPE610 handles touch events with ts.touched() polling, but I started heading down the path of using the IRQ as a way to interrupt the MM.
Attachments
remap crop.jpg
remap crop.jpg (257.17 KiB) Viewed 395 times

User avatar
XRAD
 
Posts: 754
Joined: Sat Nov 19, 2016 3:28 pm

Re: XRAD'S PLASMA ENGINE

Post by XRAD »

That is s great info! THX. As far as the IRQ(pen), I was having some issues because my code is based on UTOUCH which (I think) uses a different chip on my ILI9341 board(but likely sending same data). I had no issues polling the touch screen in my current breadboard setup. In fact it works VERY well. But I could not get UTOUCH to work with the Feather version of ILI9341 screen and touch chip. I will spend some more time on this. I think it is just a matter of pin selections but it could be in the background lib code....The needed data pins of feathers are set for hardware pins which makes popping them on to one another easier, and then they don't have to be labelled on every board. But once I solder the Teensy to the feather adapter, those pins are 'assigned' by hardware design.

The pins in your pic are for the TFT, SD, TFTDC, PLUS RT chip select for touch. There are 5 needed pins for touch data for UTOUCH:
IRQ (pen)
Touch OUT (miso)
touch IN (mosi)
touch CS == TCS == RT == pin #3 on Teensy feather
touch CLK

There are five pins on the Feather touch chip.

RT CS
SCLK
MISO
MOSI
RT INT ==IRQ == PEN

There is also a way to set touch limits on the feather : XL, XR, YU, YD.... and I see this in the example code. But not a way to access the actual touch chip miso,mosi, clk pins, which I need.....

We can find TCS and IRQ, just need the other three. At least then I can use my UTOUCH lib.

Since I am using a Teensy Feather, I had to spend some time digesting the teensy to feather pin diagrams I/O's... still a work in progress to get off the breadboard. Trying to back trace the feather teensy 3x pins, in combination with the know hardware miso,mosi,sck, sdcs,mp3cs,dreq,xdcs on the MM to get each feather pin assignment correct so that I can use the TFT w/touch AND MM. I need a big erase board! At least if I have them all figured out, I think I can put the three together using hardware instead of code to blend shared pins.....

https://github.com/adafruit/Adafruit-Te ... ematic.png

and for the Feather TFT/Touch chip schematic and the board schematic:
https://learn.adafruit.com/adafruit-2-4 ... /downloads

I tried to move around the CS and DC pins for the MM using appropriate choice pins on Teensy with limited success.

Current pin assignments Teensy:
0
1
2 IRQ(pen)
3 Touch MISO
4 Touch MOSI
5 Touch CS
6 Touch CLK
7 TFT MOSI (TFT MISO not used)
8 TFT DC
9 TFT RST
10 TFT CS
11 // was MM MOSI
12 //was MM MISO
13 //was MM CLK
14 TFT SCK
15
16 NEOPIX PIN
17
18 SDA on 20 watt amp //was MM DREQ
19 SCL on 20 watt amp //was MM DCS
20 //was MM SDCS
21 //was MM CS
22 plasmaButton
23 PWM out to TurboFan

using these pins for the MM did work great, for about 5 min.....showed the file list and played the files correctly without interruption to the program. LL levels and connections are all OK. Tested different configuration for hours..... no luck unless just running the MM by itself...

The teensy has 33 GPIO pins but really certain pins 0-21 are best for CS,SCK,O,I, etc... when you mount the teensy to the Feather adapter, you lose about 1/2 of the pins, which is why this is challenging without knowing how to parse bytes for interleaving on multipurpose pins....

So unfortunately, for my project, I would need the Adafruit TFT/Touch breakout board.....(or not! See next post)
Attachments
hot coffee.jpg
hot coffee.jpg (231.34 KiB) Viewed 381 times
Last edited by XRAD on Tue Nov 27, 2018 1:03 am, edited 1 time in total.

User avatar
XRAD
 
Posts: 754
Joined: Sat Nov 19, 2016 3:28 pm

Re: XRAD'S PLASMA ENGINE

Post by XRAD »

FINALLY! Plasma Engine Code LIVES!! Here is a question for all of you: How many times do you check your jumper cables?? My answer is not nearly as much as I should. I noticed a red power line with a few small cracks. Cheap plastic coating, and cheaper 'copper' wire underneath was almost completely fractured. So I replaced the line and my code and ALL configurations still did not work... So then I checked ALL my jumpers and guess what. A black ground line had absolutely ZERO electron flow, but it looked perfect on the outside!! I replaced this line (actually tore it up into little bits and threw them into a far corner.. I think this wire cost me 10 hours of my life) and reconfigured all the pins the way I thought they should be, and it all came together. The feather Music Maker recognizes and plays my wavs perfectly without the horrible modem sounds. If you ever wondered what a 'ground' line sounds like, it sounds like a modem going through your Music Maker speaker output.

There is no screen interruption or delay or interference while running the pixels and the sound or the PWM ducted fan. Also, I am not using musicPlayer.feedBuffer(); although I left it commented out in the loop. Also, I am using mono 16 bit 22050Hz .wavs without issue. If your MM sounds don't play, make sure track names match, including capital letters. You do not need to name the track BOOT.WAV on the SD if it is already saved as a .wav. The file lister will recognize the .wav file type and so does the palyer.

NOTE: I used a trick here to get the sound files to stop and not restart when millis timer is up on the burn effect. The burnerTimer is 5000ms, and the wav's had to be about 5.3 sec - 5.5 sec in order for the MM to get the signal to stop playing completely. This way, the NEOPIX show and the sounds work perfectly together using the millis timer.

Here is my newest code. I did not erase the previous code in prior post because its nice to see the comparison. I like order so all the pins are configured pretty much in order (except the Clock pins) for the TOUCH, TFT, and MM and relabeled here for this code:

Current pin assignments:

last updated 3/9/19

PRIMARY BOARD: TEENSY 3.2
0 Green led , plasma on pin
1 pixiepin
2 Touch IRQ (pen)
3 Touch MISO
4 Touch MOSI
5 Touch CS
6 Touch CLK
7 TFT MOSI (note: TFT MISO not used)
8 TFT DC
9 TFT RST
10 TFT CS
11 MM MOSI
12 MM MISO
13 MM CLK (SCK)
14 TFT SCK
15 MM CARDCS (there is also an SD on the ILI9341 board)
16 MM CS (MP3CS)
17 MM DREQ
18 SDA on 20 watt amp (predefined in the amplifier lib)
19 SCL on 20 watt amp (predefined in the amplifier lib)
20 MM XDCS
21 Green led , turbo on pin (might have to swap 21 to 25 or 26 to open for servo pin)
22 plasmaButton (the main BIG RED trigger button to run all your GUI choices)
23 PWM out to TurboFan

PERIPHERALS and Trinket M0 #1 and #2
24 POWERLED// on when system powered up
25 FIRELED// (RED LED) on when trigger button pushed
26 FIREBURNERPIN 28 // when PIN HIGH, triggered high amp burners
27 READYLED, green color
28 CHARGINGLED , red
29 LIGHT VALVE ?maybe? (High to close)

30 RASMABUTTON PIN 0 TM0 #1 Neopixel
31 BLASMABUTTON PIN 1 TM0 #1 Neopixel
32 GRASMABUTTON PIN 2 TM0 #1 Neopixel
33 SPASMABUTTON PIN 3 TM0 #1Neopixel


Screenshot of the MM files and 'darkside' Arduino IDE. It is a real joy using the MM feather. Easy to make and add files to my code w/Audacity.
Plasma Engine Sound Works.JPG
Plasma Engine Sound Works.JPG (97.9 KiB) Viewed 372 times

I needed to chill after the 'jumper' fiasco so I built one of these:
IMG_2820.JPG
IMG_2820.JPG (158.37 KiB) Viewed 372 times
Last edited by XRAD on Wed Mar 13, 2019 7:14 pm, edited 8 times in total.

User avatar
XRAD
 
Posts: 754
Joined: Sat Nov 19, 2016 3:28 pm

Re: XRAD'S PLASMA ENGINE

Post by XRAD »

This will be the 'final' code. Any updates will go here. Don't forget your font .c and image files (which I have not yet included). Updated Teensy PIN connections listed in above post.

NOTE: I have not included the font or the x2 image files. will add them when all done
NOTE to self: post character limit is 60000!

Last Update:
11/29/18 added new Pixie show() code and button control code for PIXIE brightness
11/30/18 added overheat protection for smoke coil
11/30/18 added shutdwn.wav and hum.wav play code
12/01/18 added musicPlayer.softReset(); and modified ( a tinly bit) the Adafruit_VS1053.cpp
12/2/18 added 'ready' and 'charging' led control(can't retrigger when red), added some debugging
12/10/18 added UTFT bitmap extern and call myGLCD.drawBitmap (x,y,length,width,image.c)
modified charging led, if red, you also have to turn on turbofan.
12/12/18 added more LED || && statements to control the GREEN/RED/BLUE leds, complex if loops due to screen selections which must be made prior to being able to trigger engine
12/14/18 added infinite interruptable background .wav loop
3/9/19 added safety digital shutoff and better burner control
3/9/19 added TrinketM0 control of 5 'noise' displays
3/9/19 added shutdown screen with mute
3/9/19 added lightvalve open/close
3/11/19 added some boolean logic for TFT display w/out pixel interrupt
3/12/19 added bootdown punishment shutdown sound for wrong button selections
3/13/19 used last 2 teensy pins for green set-up leds, added bool control for single play audio track
re-wrote portion of button control code. moved pixie pin to tx1
3/13/19 added interruptable forever sound loop now begins in setup
3/14/19 added shutdown screens and sound effects and led control
3/17/19 fixed sound level slider touch control
3/18/19 limited turbo fan function to trigger button and turbovolume page
3/19/19 fixed the switch case turbo map PWM and same Pixie combo functions
3/20/19: as far as I can tell => CODE DONE!! <= :)


Code: Select all


/*  *****XRAD'S PLASMA ENGINE **********

    Another frankencode for one of my projects. Some of the code comes from
    Adafruit tutorials:
    https://learn.adafruit.com/adafruit-2-4-tft-touch-screen-featherwing/resistive-touch-screen
    https://learn.adafruit.com/adafruit-20w-stereo-audio-amplifier-class-d-max9744/overview
    https://learn.adafruit.com/fiber-optic-pixie-princess-skirt/code
    https://learn.adafruit.com/pixie-3-watt-smart-chainable-led-pixels/design
    and some from:
    https://howtomechatronics.com/tutorials/arduino/arduino-tft-lcd-touch-screen-tutorial/
    jpg image converter for UTFT image display:
    http://www.rinkydinkelectronics.com/_t_doimageconverter565.php

      The rest I just imagined or cobbled together from my older projects.......
    I am using ILI9341 TFT 2.8"Touch, simple I2C control of volume mapped to the MAX9774
    and Teensy 3.2 as main processor. There is a 5 sec MAX burn time and then 
    2 sec off time which you will see if you hold the trigger button in ON position.

    You must choose a plasma color and set the turboVolumeRange to greater than 0
     (both conditions have to be met). Once both of these selections
    are chosen, and you are on the 'Home' page, the 3 GREEN leds will light up and you can 
    then trigger the engine 'on' w/main trigger button.  Otherwise, the PIXIES/Burner will 
    not light up and the red chargingLED will be 'on.' This is to make sure the turboFan is 
    running so that the burner coil and Pixies do not overheat.  Interruptable background 
    .wav loop. Shutdown sound when conditions not met. Every teensy 3.2 pin used!

*/

#include <Wire.h>
#include <SD.h>
#include <Servo.h>
#include <UTFT.h>
#include <URTouch.h>
#include <Adafruit_VS1053.h>
#include <SD.h>
#include <SoftwareSerial.h>
#include <Adafruit_Pixie.h>


// define pins to Music Maker
#define VS1053_RESET   -1     // VS1053 reset pin (not used!)

#define CARDCS         15   // Card chip select pin
#define VS1053_CS      16     // VS1053 chip select pin (output)
#define VS1053_DREQ    17     // VS1053 Data request, ideally an Interrupt pin
#define VS1053_DCS     20     // VS1053 Data/command select pin (output)

#define VS1053_MOSI    11
#define VS1053_MISO    12
#define VS1053_SCK     13


//define some basic Teensy pins
#define PLASMABUTTON   22 //trigger button to fire plasma pixies ONLY when on home screen

#define PLASMAONPIN     0 //pixie output
#define TURBOONPIN     21  //pixie output

#define PIXIEPIN       1 //pixie output
#define NUMPIXELS      3 // # of Pixies

#define POWERLED       24 // (BLUE LED)  on when powered up
#define FIRELED        25 // (RED LED) inside master switch, only red when button pushed in and plasma engine 'ON'
#define FIREBURNERPIN  26 // when PIN HIGH, triggers high amp burners and red led
#define READYLED       27 // (GREEN LED) ok to fire Plasma Engine when lit
#define CHARGINGLED    28 // (RED LED) Cannot fire Plasma Engine when lit

#define LIGHTVALVEPIN  29 // CLOSED when PIN HIGH , OPEN when PIN LOW


//TM0 PLASMA

#define  RASMABUTTON   30 //goes to input PIN 1
#define  BLASMABUTTON  31 //goes to input PIN 3 
#define  GRASMABUTTON  32 //goes to input PIN 2
#define  SPASMABUTTON  33 //goes to input PIN 0



SoftwareSerial pixieSerial(-1, PIXIEPIN);// -1 Pin because only Tx needed
Adafruit_Pixie strip = Adafruit_Pixie(NUMPIXELS, &pixieSerial);

//Adafruit_Pixie strip = Adafruit_Pixie(NUMPIXELS, &Serial1); //use for serial hardware if available, but does not transmit serial pixel data for some reason

int  myColors[][3] = {
  {255,   0,   0},   // red
  {255, 150,   0},   // orange
  {0  ,   0, 255},   // blue
  {200,   0, 200},   // purple
  {0  , 255,   0},   // green
  {251, 255,   0},   // yellow
  {150, 150, 150},   // white
};

//==for pixie dispaly
#define  MYCOLORS sizeof(myColors) / 7

// describes the pins used on Teensy 3x to 20 watt amp
#define MAX9744_I2CADDR 0x4B
//  MAX9744_SDA to  18   defined in lib
//  MAX9744_SCL to 19    defined in lib
//  MAX9744 Vi2C to 3.3v on Teensy

//==== Declare a bunch of stuff ========

//==millis timers
int plasmaButtonState = 0;
int lastPlasmaButtonState = 0;
int fireBurnerState = 0;
unsigned long plasmaButtonTimer = 7000;//off timer starts same time as 'on' timer, then resets
unsigned long plasmaBurnerTimer = 5000;//max on timer,shuts off burner+sound+Pixies
unsigned long startMillis;
unsigned long currentMillis;

//==some basic fonts
extern uint8_t SmallFont[]; //comes w/UTFT
extern uint8_t BigFont[]; // comes w/UTFT
extern uint8_t SevenSegNumFont[]; //comes w/UTFT
extern uint8_t GroteskBold24x48[]; //font works

//==small converted jpgs
extern unsigned short radioactive[];
extern unsigned short engsml[];


int selectLED;  // for neopix display type (0,1,2,3)
int stateLED = 0;

int x, y; // for touch screen position

char currentPage; //current TFT page

// initial sound screen level setting
int xR = 100; //initial setting sound level slider position


//====== turboFan  ====//turbofan PWM pin 23 attached as servo1

int turboVolumeRange ;
int iV ; // 0-9 for display on plasma volume bottom right start:0
#define turboMin  95  //no throttle, setting will depend on ESC
#define turboMax  110 //full throttle, setting will depend on ESC

int turboPWM;//for PWM output setting during loop


//======= Pixie Brightness ====

int pixieBrightnessRange = 0;
int iP  ;
#define pixieMin 20 // just seeing light
#define pixieMax  250 // blinding bright
int pixieStartPos = 20;

//======
int countdownStart = 6;  // for the start up count down timer, have to start at 6 because only 5 counts down

int humState = 0;  // for the short SHUTDWN.WAV

//==== Creating Some Objects

UTFT myGLCD(ILI9341_S5P, 7, 14, 10, 8, 9); // (ILI9341_S5P, MOSI, SCK, CS, RST,DC)
URTouch  myTouch( 6, 5, 4, 3, 2); // ( CLK, TCS, MOSI, MISO, IRQ(PEN))
Servo servo1; // for turbofan

Adafruit_VS1053_FilePlayer musicPlayer =
  Adafruit_VS1053_FilePlayer(VS1053_RESET, VS1053_CS, VS1053_DCS, VS1053_DREQ, CARDCS);


int ledPins[] = {24, 0, 21, 27, 25, 26, 28}; //LED pins{POWERLED,PLASMAONPIN, TURBOONPIN,READYLED, FIRELED,FIREBURNERPIN,CHARGINGLED}
int numLedPins = 7;

int plasmaPins[] = {30, 31, 32, 33 }; //plasma TM0 pins{RASMABUTTON,BLASMABUTTON,GRASMABUTTON,SPASMABUTTON}
int numPlasmaPins = 4;


boolean donePlasmaFiring = false;//used so that true v false is easy to identify in program
boolean donePlasmaNotFiring = false;//x2 of these bools because x2 TFT draw button changes

boolean  doneDownState = false;//for SHTDWNB.WAV


//=================================
//============= setup =============
//=================================

void setup() {
  digitalWrite(PLASMAONPIN, LOW);//patch because pin 0 goes high on boot
  pinMode(LIGHTVALVEPIN, OUTPUT);
  digitalWrite(LIGHTVALVEPIN, HIGH);
  delay(40);

  myGLCD.InitLCD();
  myGLCD.clrScr(); //do this  first

  plasmaIgnition();
  delay (1000);
  myGLCD.clrScr();

  Serial.begin(9600);//serial monitor begin
  Wire.begin();

  pinMode(PLASMABUTTON, INPUT_PULLDOWN);

  for (int i = 0; i < numPlasmaPins; i++) {
    pinMode(plasmaPins[i], OUTPUT); // Set to OUTPUT
  }

  for (int i = 0; i < numLedPins; i++) {
    pinMode(ledPins[i], OUTPUT); // Set to OUTPUT
  }

  for (int p = 0; p < numLedPins; p++) {
    digitalWrite(ledPins[p], HIGH);
    delay(250);
    digitalWrite(ledPins[p], LOW);
    delay(250);
  }

  pixieSerial.begin(115200); //115200 required by pixies

  //Serial1.begin(115200); //use for serial hardware if available but does not transmit pixel data for some reason

  musicPlayer.begin();
  Serial.println("player begin");
  //musicPlayer.sineTest(0x44, 500); //Make a tone to indicate VS1053 is working
  SD.begin(CARDCS);
  musicPlayer.setVolume(0, 0);//0 is loudest, 100 is no sound
  musicPlayer.useInterrupt(VS1053_FILEPLAYER_PIN_INT);  // DREQ int

  //list files if needed
  printDirectory(SD.open("/"), 0);
  Serial.println("player begin");
  delay (50);

  startMillis = millis();

  digitalWrite (POWERLED, HIGH);

  myTouch.InitTouch();
  myTouch.setPrecision(PREC_MEDIUM);

  myGLCD.drawBitmap (100, 50, 128, 128, radioactive); //draw first image on boot up

  servo1.attach(23);
  servo1.write(turboMin);
  delay(50);
  Serial.print("Setting turbo to ");
  Serial.println(turboMin);

  strip.setBrightness(pixieStartPos);
  //pixie brightness 0-255 also now set in brightness control

  musicPlayer.softReset();
  musicPlayer.startPlayingFile("WARNING.WAV"); // plays for 2.5sec before boot
  Serial.println("WARNING.WAV");
  delay(2500);
  musicPlayer.softReset();
  musicPlayer.startPlayingFile("BOOT.WAV");
  Serial.println("BOOT.WAV");

  myGLCD.clrScr();//  clean screen all up before displaying anything else

  digitalWrite (LIGHTVALVEPIN, LOW);
  warningHomeScreen(); // the special warning screen function
  drawHomeScreen();  // Draws the Home Screen
  currentPage = '0'; //  Home Screen '0' set as baseline

  digitalWrite (POWERLED, HIGH);

  if (musicPlayer.stopped())  {
    playBackground();
  }

}



//========================================
//============= Main Loop ================
//========================================

void loop() {

  currentMillis = millis();
  plasmaWindowShow();


  //========== Home Page button contol=============

  if (currentPage == '0') {


    if (myTouch.dataAvailable()) {
      myTouch.read();
      x = myTouch.getX(); // X coordinate where the screen has been pressed
      y = myTouch.getY(); // Y coordinates where the screen has been pressed


      //   press the Plasma Color Button
      if ((x >= 35) && (x <= 285) && (y >= 90) && (y <= 130)) {
        drawFrame(35, 90, 285, 130); // Custom Function -Highlights button edge when pressed
        currentPage = '1';  //move to select 'x' page
        myGLCD.clrScr(); // Clears the screen
        drawPlasmaControl(); // It is called once and draws the first page.

      }

      //   press the Sound Level Button
      if ((x >= 35) && (x <= 285) && (y >= 140) && (y <= 180)) {
        drawFrame(35, 140, 285, 180);
        currentPage = '2'; //move to select 'x' page
        myGLCD.clrScr();
        drawSoundControl();
      }

      //   press the Plasma Volume Button
      if ((x >= 35) && (x <= 285) && (y >= 190) && (y <= 230)) {
        drawFrame(35, 190, 285, 230);
        currentPage = '3'; //move to select 'x' page
        myGLCD.clrScr();
        drawPlasmaVolume();
      }
    }
  }

  // Page 1: Plasma Color  button press control
  if (currentPage == '1') {
    neopixelShow();

    if (myTouch.dataAvailable()) {
      myTouch.read();
      x = myTouch.getX();
      y = myTouch.getY();

      // If we press the RASMA Button
      if ((x >= 10) && (x <= 150) && (y >= 115) && (y <= 163)) {
        drawFrame(10, 115, 150, 163); // Custom Function -Highlights button when pressed
        selectLED = '0';
        Serial.println("selectLED RASMA");
      }

      // If we press the BLASMA Button
      if ((x >= 170) && (x <= 310) && (y >= 115) && (y <= 163)) {
        drawFrame(170, 115, 310, 163);
        selectLED = '1';
        Serial.println("selectLED BLASMA");
      }

      // If we press the GRASMA Button
      if ((x >= 10) && (x <= 150) && (y >= 173) && (y <= 221)) {
        drawFrame(10, 173, 150, 221);
        selectLED = '2';
        Serial.println("selectLED GRASMA");
      }

      // If we press the SPASMA Button
      if ((x >= 170) && (x <= 310) && (y >= 173) && (y <= 221)) {
        drawFrame(170, 173, 310, 221);
        selectLED = '3';
        Serial.println("selectLED SPASMA");
      }


      // Back Button control
      if ((x >= 10) && (x <= 60) && (y >= 10) && (y <= 36)) {
        drawFrame(10, 10, 60, 36);
        currentPage = '0'; //move to select 'x' page
        myGLCD.clrScr();
        drawHomeScreen(); // Draws the home screen
      }

      // button to brightness  control
      if ((x >= 258) && (x <= 308) && (y >= 10) && (y <= 36)) {
        drawFrame(258, 10, 308, 36);
        currentPage = '4';
        myGLCD.clrScr();
        drawPlasmaBrightness(); // Draws the pixie brightness screen
      }
    }
  }

  // Page 2: Sound level  button press contol

  if (currentPage == '2') {

    if (myTouch.dataAvailable()) {
      myTouch.read();
      x = myTouch.getX();
      y = myTouch.getY();

      if ( (y >= 130) && (y <= 160)) {
        setSoundLevel();
      }

      else {
        //Back button
        if ((x >= 10) && (x <= 60) && (y >= 10) && (y <= 36)) {
          drawFrame(10, 10, 60, 36);
          currentPage = '0';
          myGLCD.clrScr();
          drawHomeScreen();
        }
        // button to infographix display
        if ((x >= 258) && (x <= 308) && (y >= 10) && (y <= 36)) {
          drawFrame(258, 10, 308, 36);
          currentPage = '6'; //move to select 'x' page
          myGLCD.clrScr();
          drawShutdownScreen();
        }
      }
    }
  }


  //Page Three: PlasmaVolume button press contol

  if (currentPage == '3') {

    donePlasmaNotFiring = true;//patch to fix holdover of 'false'



    myGLCD.setColor(0, 255, 0);
    myGLCD.setFont(SevenSegNumFont);
    myGLCD.setBackColor(200, 0, 200);
    myGLCD.print(iV, 193, 177);

    if (myTouch.dataAvailable()) {
      myTouch.read();
      x = myTouch.getX();
      y = myTouch.getY();

      // DECREASE Button

      if ((x >= 10) && (x <= 150) && (y >= 115) && (y <= 163)) {
        drawFrame(10, 115, 150, 163);
        if ((iV >= 0) && (iV <= 9)) {
          iV--;
          if (iV <= 0) {
            iV = 0;
          }
        }
        setPlasmaVolume();
      }


      // INCREASE Button

      if ((x >= 170) && (x <= 310) && (y >= 115) && (y <= 163)) {
        drawFrame(170, 115, 310, 163);
        if ((iV >=  0) && (iV <= 9)) {
          iV++;
          if (iV >= 9) {
            iV = 9;
          }
        }
        setPlasmaVolume();
      }




      //Back button
      if ((x >= 10) && (x <= 60) && (y >= 10) && (y <= 36)) {
        drawFrame(10, 10, 60, 36);
        currentPage = '0';
        myGLCD.clrScr();
        drawHomeScreen();
      }

      // button to infographix display
      if ((x >= 258) && (x <= 308) && (y >= 10) && (y <= 36)) {
        drawFrame(258, 10, 308, 36);
        currentPage = '5'; //move to select 'x' page
        myGLCD.clrScr();
        drawInfographixsBack(); // call to display custom bitmap and back button
      }

    }
  }


  // pixie brightness touch

  if (currentPage == '4') {

    myGLCD.setColor(0, 255, 0);
    myGLCD.setFont(SevenSegNumFont);
    myGLCD.setBackColor(200, 0, 200);
    myGLCD.print(iP, 193, 177);

    if (myTouch.dataAvailable()) {
      myTouch.read();
      x = myTouch.getX();
      y = myTouch.getY();

      // DECREASE Button
      if ((x >= 10) && (x <= 150) && (y >= 115) && (y <= 163)) {
        drawFrame(10, 115, 150, 163);
        if ((iP >= 0) && (iP <= 9)) {
          iP--;
          if (iP <= 0) {
            iP = 0;
          }
        }
        setPixieBrightness();
      }

      // INCREASE Button
      if ((x >= 170) && (x <= 310) && (y >= 115) && (y <= 163)) {
        drawFrame(170, 115, 310, 163);
        if ((iP >=  0) && (iP <= 9)) {
          iP++;
          if (iP >= 9) {
            iP = 9;
          }
        }
        setPixieBrightness();
      }

      //Back button
      if ((x >= 10) && (x <= 60) && (y >= 10) && (y <= 36)) {
        drawFrame(10, 10, 60, 36);
        currentPage = '1';
        myGLCD.clrScr();
        drawPlasmaControl();
      }
    }
    neopixelShow();// start the pixie show!
  }



  // Page 5: Infographixs  button press control

  if (currentPage == '5') {

    if (myTouch.dataAvailable()) {
      myTouch.read();
      x = myTouch.getX();
      y = myTouch.getY();

      // Back Button control
      if ((x >= 10) && (x <= 60) && (y >= 10) && (y <= 36)) {
        drawFrame(10, 10, 60, 36);
        currentPage = '3'; //move to select 'x' page
        myGLCD.clrScr();
        drawPlasmaVolume();
      }
    }
  }

  // Page 6: SHutdown button press control

  if (currentPage == '6') {

    if (myTouch.dataAvailable()) {
      myTouch.read();
      x = myTouch.getX();
      y = myTouch.getY();
      //   press the <- Main button
      if ((x >= 35) && (x <= 285) && (y >= 90) && (y <= 130)) {
        drawFrame(35, 90, 285, 130); // Custom Function -Highlights button edge when pressed
        currentPage = '0';  //move to select 'x' page
        myGLCD.clrScr(); // Clears the screen
        drawHomeScreen();
      }
      //   press the Shutdown button
      if ((x >= 35) && (x <= 285) && (y >= 140) && (y <= 180)) {
        drawFrame(35, 140, 285, 180);
        currentPage = '7'; //move to select 'x' page
        musicPlayer.stopPlaying();
        musicPlayer.softReset();
        musicPlayer.startPlayingFile("SHTDWNB.WAV"); //SHUTDOWN.WAV is 1.3sec long

        Serial.println("SHTDWNB.WAV");
        digitalWrite (LIGHTVALVEPIN, HIGH);
        drawPowerDown();
        drawOffScreen();
        musicPlayer.softReset();
        musicPlayer.startPlayingFile("BEEP.WAV");
        Serial.println("BEEP.WAV");
        delay(5000);
        //musicPlayer.stopPlaying();//the humm loop keeps this from happening
        musicPlayer.setVolume(100, 100);//super low volume
      }
    }
  }


  //====== MAIN BUTTON CONTROL======

  plasmaButtonState = digitalRead(PLASMABUTTON);

  //this 'if' section works fine......

  if ((plasmaButtonState == HIGH) && (currentPage == '0' ) && (currentMillis - startMillis < plasmaButtonTimer) && (turboVolumeRange > 0)) {
    if  (currentMillis - startMillis < plasmaBurnerTimer) {
      plasmaEngineSound();
      digitalWrite (FIREBURNERPIN, HIGH);
      digitalWrite (FIRELED, HIGH);
      digitalWrite (CHARGINGLED, LOW);
      digitalWrite (READYLED, HIGH);
      neopixelShow();

      servo1.write( turboPWM ); //turbo on

      donePlasmaNotFiring = false;//so the plasmanotfiring()can run once
      doneDownState = false;//so the shutdown()can run once
      lastPlasmaButtonState = 1;
    }

    if (donePlasmaFiring == false) {
      plasmaFiring();
    }

    if ((plasmaButtonState == HIGH) && (currentMillis - startMillis >= plasmaBurnerTimer)) {
      fireBurnerState = 1;
      if (fireBurnerState == 1) {
        digitalWrite (FIREBURNERPIN, LOW);
        digitalWrite (FIRELED, LOW);
        digitalWrite (READYLED, LOW);
        digitalWrite (CHARGINGLED, HIGH);
        servo1.write( turboMin );
        colorWipe(strip.Color (0 , 0, 0), 10);
        strip.show();
      }
    }

    if (humState == 0) {//helps to initiate the background hum sound loop in next section
      humState = 1;
    }
  }

  //this else{} needs cleaning up but works fine as is.....
  else  {
    startMillis = currentMillis;

    if (currentPage == '3') {
      servo1.write( turboPWM );//turbo on if this condition
    }
    else {
      servo1.write( turboMin );//turbo off all other conditions, except for HIGH main button
    }


    if (plasmaButtonState == LOW) {
      digitalWrite (FIREBURNERPIN, LOW);
      digitalWrite (FIRELED, LOW);
      fireBurnerState = 0;
    }

    if ((selectLED != '0') || (selectLED != '1') || (selectLED != '2') || (selectLED != '3')) {
      if ((plasmaButtonState == LOW) && (currentPage == '0' ) && (humState == 1) || (turboVolumeRange == 0))  {
        digitalWrite (READYLED, LOW);
        digitalWrite (CHARGINGLED, HIGH);
      }
    }

    if ((selectLED == '0') || (selectLED == '1') || (selectLED == '2') || (selectLED == '3')) {
      if ((plasmaButtonState == LOW) && (currentPage == '0' ) && (humState == 1) || (turboVolumeRange > 0))  {

        if ((currentPage == '2') || (currentPage == '7')  || (currentPage == '6') || (currentPage == '5')) { //patch to fix
          digitalWrite (READYLED, LOW);
        }
        else {
          donePlasmaFiring = false;//so the plasmafiring() can run once
          digitalWrite (READYLED, HIGH);
          digitalWrite (CHARGINGLED, LOW);
        }
        if (donePlasmaNotFiring == false) {
          plasmaNotFiring();
        }
      }
    }


    if ((selectLED == '0') || (selectLED == '1') || (selectLED == '2') || (selectLED == '3')) {
      if ((plasmaButtonState == LOW) && (currentPage == '0' ) && (humState == 1))  {
        if (plasmaButtonState != lastPlasmaButtonState) {
          colorWipe(strip.Color (0 , 0, 0), 10);//sets pixies to zero
          strip.show();
          musicPlayer.stopPlaying();
          humState = 0;

          if ((musicPlayer.stopped()) && (humState == 0)) {
            musicPlayer.softReset();
            musicPlayer.startPlayingFile("SHUTDWN.WAV"); //SHUTDOWN.WAV is 1.3sec long
            digitalWrite (CHARGINGLED, HIGH);
            digitalWrite (READYLED, LOW);
            Serial.println("SHUTDWN.WAV");
            delay(1500);// needed or else the call to play HUM.WAV will be missed
          }

          if ((musicPlayer.stopped()) && (humState == 0)) {
            digitalWrite (CHARGINGLED, LOW);
            playBackground();
          }
        }
      }
    }
  }


  //these 'if's' work fine....
  if ((plasmaButtonState == HIGH) && (currentPage != '0')) {
    if (doneDownState == true) { //so the shutdown()can run once
      musicPlayer.stopPlaying();
    }
    if (doneDownState == false) {
      buttonDown();
    }
  }


  if ((selectLED != '0') || (selectLED != '1') || (selectLED != '2') || (selectLED != '3') ) {
    if (turboVolumeRange == 0)  {
      if ((plasmaButtonState == HIGH) && (currentPage == '0')) {
        if (doneDownState == true) { //so the shutdown()can run once
          musicPlayer.stopPlaying();
        }
        if (doneDownState == false) {
          buttonDown();
        }
      }
    }
  }


  if  (currentPage != '0') {
    digitalWrite (CHARGINGLED, HIGH);
    digitalWrite (READYLED, LOW);
  }


  if ((selectLED == '0') || (selectLED == '1') || (selectLED == '2') || (selectLED == '3')) {
    if (currentPage != '7') {
      digitalWrite (PLASMAONPIN, HIGH);
    }
  }
  else {
    digitalWrite (PLASMAONPIN, LOW);
  }

  //if (turboVolumeRange > 0) {
  if (iV > 0) {
    if (currentPage != '7') {
      digitalWrite (TURBOONPIN, HIGH);
    }
  }
  else {
    digitalWrite (TURBOONPIN, LOW);
  }

  if (currentPage == '7') {
    digitalWrite (CHARGINGLED, LOW);
    delay(400);
    digitalWrite (CHARGINGLED, HIGH);
    delay(250);
  }
}



//===========================================
//== Custom Background Sound Functions ==
//===========================================

void buttonDown () {
  musicPlayer.stopPlaying();
  digitalWrite (READYLED, LOW);
  digitalWrite (CHARGINGLED, HIGH);
  musicPlayer.softReset();
  musicPlayer.startPlayingFile("BUTDWN.WAV"); //BUTDOWN.WAV is 3 sec long
  Serial.println("BUTDWN.WAV");
  colorWipe(strip.Color (0 , 0, 0), 10);
  strip.show();
  delay(2000);//delay so you can't play another sound or do anything (punishment for not selecting correct settings)
  // musicPlayer.stopPlaying();
  doneDownState = true;//so the shutdown()can run once
}



void plasmaEngineSound() {

  if (selectLED == '0' ) {
    if (musicPlayer.stopped()) {
      musicPlayer.softReset();
      musicPlayer.startPlayingFile("RASMA.WAV"); // making new sound files
      Serial.println("RASMA.WAV");
    }
  }
  if (selectLED == '1' ) {
    if (musicPlayer.stopped()) {
      musicPlayer.softReset();
      musicPlayer.startPlayingFile("BLASMA.WAV");
      Serial.println("BLASMA.WAV");
    }
  }
  if (selectLED == '2' ) {
    if (musicPlayer.stopped()) {
      musicPlayer.softReset();
      musicPlayer.startPlayingFile("GRASMA.WAV");
      Serial.println("GRASMA.WAV");
    }
  }
  if (selectLED == '3' ) {
    if (musicPlayer.stopped()) {
      musicPlayer.softReset();
      musicPlayer.startPlayingFile("SPASMA.WAV");
      Serial.println("SPASMA.WAV");
    }
  }
}




void playBackground () {

  plasmaButtonState = digitalRead(PLASMABUTTON);

  if (musicPlayer.stopped()) {
    musicPlayer.softReset();
    musicPlayer.startPlayingFile("HUM.WAV");
    Serial.println("HUM.WAV");
  }
  if (musicPlayer.playingMusic) {
    loop();
  }

  if (plasmaButtonState == HIGH) {
    musicPlayer.stopPlaying();
    Serial.println("STOP PLAY");
  }
  else {
    playBackground ();
  }
}



//=============================================
//=========== Custom Draw Funtions ============
//=============================================
void plasmaIgnition() {
  myGLCD.setColor(250, 0, 0); // Sets green color
  myGLCD.fillRoundRect (35, 90, 285, 130); // Draws filled rounded rectangle
  myGLCD.setColor(255, 255, 255); // Sets color to white
  myGLCD.drawRoundRect (35, 90, 285, 130); // Draws rounded rectangle without a fill, so the overall appearance of the button looks like it has a frame
  myGLCD.setFont(BigFont); // Sets the font to big
  myGLCD.setBackColor(250, 0, 0); // Sets the background color of the area where the text will be printed to green, same as the button
  myGLCD.print("PLASMA IGNITION", CENTER, 102); // Prints the string
}


void plasmaFiring() {
  myGLCD.setColor(250, 0, 0); // Sets green color
  myGLCD.fillRoundRect (35, 90, 285, 130); // Draws filled rounded rectangle
  myGLCD.setColor(255, 255, 255); // Sets color to white
  myGLCD.drawRoundRect (35, 90, 285, 130); // Draws rounded rectangle without a fill, so the overall appearance of the button looks like it has a frame
  myGLCD.setFont(BigFont); // Sets the font to big
  myGLCD.setBackColor(250, 0, 0); // Sets the background color of the area where the text will be printed to green, same as the button
  myGLCD.print("PLASMA FIRING", CENTER, 102); // Prints the string
  donePlasmaFiring = true; //so the plasmafiring() runs once
}

void plasmaNotFiring() {
  myGLCD.setColor(228, 7, 215); // Sets green color
  myGLCD.fillRoundRect (35, 90, 285, 130); // Draws filled rounded rectangle
  myGLCD.setColor(255, 255, 255); // Sets color to white
  myGLCD.drawRoundRect (35, 90, 285, 130); // Draws rounded rectangle without a fill, so the overall appearance of the button looks like it has a frame
  myGLCD.setFont(BigFont); // Sets the font to big
  myGLCD.setBackColor(228, 7, 215); // Sets the background color of the area where the text will be printed to green, same as the button
  myGLCD.print("PLASMA COLOR", CENTER, 102); // Prints the string
  donePlasmaNotFiring = true;// so the plasmanotfiring()runs once
}




//==draws  home screen warning======
//runs once on setup and counts down 5 to 0, but does not show the zero

void warningHomeScreen() {
  for (int i = 0  ; i < 5  ; i++) {
    myGLCD.setColor(255, 0, 0); // Sets color to white
    myGLCD.drawRoundRect (60, 28, 255, 80);
    myGLCD.drawRoundRect (50, 18, 265, 90);
    myGLCD.drawCircle (160, 190, 40);
    myGLCD.setFont(GroteskBold24x48);
    myGLCD.setBackColor(0, 0, 0);
    myGLCD.print("WARNING", CENTER, 30);
    myGLCD.setFont(SmallFont);
    myGLCD.setColor(255, 255, 255);
    myGLCD.print("PLASMA ENGINE IGNITION IN:", CENTER, 115);
    countdownStart = (countdownStart - 1);
    myGLCD.setFont(SevenSegNumFont);
    myGLCD.setColor(0, 255, 0);
    myGLCD.print(countdownStart, CENTER, 165);
    digitalWrite (READYLED, HIGH);
    digitalWrite (CHARGINGLED, HIGH);
    digitalWrite (POWERLED, HIGH);
    digitalWrite (FIRELED, HIGH);
    digitalWrite (FIREBURNERPIN, HIGH);
    digitalWrite (PLASMAONPIN, HIGH);
    digitalWrite (TURBOONPIN, HIGH);
    delay (200);
    digitalWrite (READYLED, LOW);
    digitalWrite (CHARGINGLED, LOW);
    digitalWrite (POWERLED, LOW);
    digitalWrite (FIRELED, LOW);
    digitalWrite (FIREBURNERPIN, LOW);
    digitalWrite (PLASMAONPIN, LOW);
    digitalWrite (TURBOONPIN, LOW);
    myGLCD.clrScr();
  }
}

//======draws Home Screen====

void drawHomeScreen() {
  myGLCD.setBackColor(0, 0, 0); // Sets the background color of the area where the text will be printed to black
  myGLCD.setColor(255, 255, 255);
  myGLCD.drawRoundRect (1, 1, 318, 238);
  myGLCD.setColor(255, 255, 255); // Sets color to white
  myGLCD.setFont(BigFont); // Sets font to big
  myGLCD.print("PLASMA ENGINE", CENTER, 10); // Prints the string on the screen
  myGLCD.setColor(255, 255, 255); // Sets color to white
  myGLCD.setFont(SmallFont); // Sets the font to small
  myGLCD.print("WARNING: MOSTLY DANGEROUS", CENTER, 35); // Prints the string  myGLCD.setFont(DotMatrix_M_Slash);
  myGLCD.print("TOASTER SETTINGS MUST BE", CENTER, 50);
  myGLCD.print("SELECTED BEFORE OPERATING", CENTER, 65);

  // Button - PLASMA COLOR
  myGLCD.setColor(228, 7, 215); // Sets green color
  myGLCD.fillRoundRect (35, 90, 285, 130); // Draws filled rounded rectangle
  myGLCD.setColor(255, 255, 255); // Sets color to white
  myGLCD.drawRoundRect (35, 90, 285, 130); // Draws rounded rectangle without a fill, so the overall appearance of the button looks like it has a frame
  myGLCD.setFont(BigFont); // Sets the font to big
  myGLCD.setBackColor(228, 7, 215); // Sets the background color of the area where the text will be printed to green, same as the button
  myGLCD.print("PLASMA COLOR", CENTER, 102); // Prints the string

  // Button - SOUND LEVEL
  myGLCD.setColor(200, 200, 0);
  myGLCD.fillRoundRect (35, 140, 285, 180);
  myGLCD.setColor(255, 255, 255);
  myGLCD.drawRoundRect (35, 140, 285, 180);
  myGLCD.setFont(BigFont);
  myGLCD.setBackColor(200, 200, 0);
  myGLCD.print("SOUND LEVEL", CENTER, 152);

  // Button - PLASMA VOLUME
  myGLCD.setColor(40, 200, 100);
  myGLCD.fillRoundRect (35, 190, 285, 230);
  myGLCD.setColor(255, 255, 255);
  myGLCD.drawRoundRect (35, 190, 285, 230);
  myGLCD.setFont(BigFont);
  myGLCD.setBackColor(40, 200, 100);
  myGLCD.print("PLASMA VOLUME", CENTER, 202);
}


//====================================================
//=== Highlights all GUI button edges when pressed====
//====================================================

void drawFrame(int x1, int y1, int x2, int y2) {
  myGLCD.setColor(255, 0, 0);
  myGLCD.drawRoundRect (x1, y1, x2, y2);
  while (myTouch.dataAvailable())
    myTouch.read();
  myGLCD.setColor(255, 255, 255);
  myGLCD.drawRoundRect (x1, y1, x2, y2);

  //musicPlayer.stopPlaying();//uncomment if you want to interrupt background HUM.WAV

  if (musicPlayer.stopped()) {//comment this line out if you do not want to interrupt HUM.WAV
    musicPlayer.softReset();
    musicPlayer.startPlayingFile("BUTTON.WAV");
    Serial.println("BUTTON.WAV");
  }
}


//=====================================================
//===== DRAW PAGE'S 1,2,3,4,5,6,7 SIMPLE GUI's=========
//=====================================================


//====drawPlasmControl Page====

void drawPlasmaControl() {

  // forward to plasma lumen control
  myGLCD.setColor(100, 155, 203);
  myGLCD.fillRoundRect (258, 10, 308, 36);
  myGLCD.setColor(255, 255, 255);
  myGLCD.drawRoundRect (258, 10, 308, 36);
  myGLCD.setFont(BigFont);
  myGLCD.setBackColor(100, 155, 203);
  myGLCD.print("->", 266, 15);

  //back to main screen
  myGLCD.setColor(100, 155, 203);
  myGLCD.fillRoundRect (10, 10, 60, 36);
  myGLCD.setColor(255, 255, 255);
  myGLCD.drawRoundRect (10, 10, 60, 36);
  myGLCD.setFont(BigFont);
  myGLCD.setBackColor(100, 155, 203);
  myGLCD.print("<-", 18, 15);
  myGLCD.setBackColor(0, 0, 0);
  myGLCD.setFont(SmallFont);
  myGLCD.print("MAIN MENU", 70, 10);
  myGLCD.print("PLASMA CONTROL", 142, 26);

  myGLCD.setFont(BigFont);
  myGLCD.print("PLASMA COLOR", CENTER, 50);
  myGLCD.print("Select for Color", CENTER, 76);
  myGLCD.setBackColor(0, 0, 0);
  myGLCD.setColor(255, 255, 255);


  myGLCD.setColor(200, 0, 0);
  myGLCD.fillRoundRect (10, 115, 150, 163);
  myGLCD.setColor(225, 255, 255);
  myGLCD.drawRoundRect (10, 115, 150, 163);
  myGLCD.setBackColor(200, 0, 0);
  myGLCD.setColor(255, 255, 255);
  myGLCD.print("RASMA", 40, 130);

  myGLCD.setColor(0, 0, 200);
  myGLCD.fillRoundRect (170, 115, 310, 163);
  myGLCD.setColor(225, 255, 255);
  myGLCD.drawRoundRect (170, 115, 310, 163);
  myGLCD.setBackColor(0, 0, 200);
  myGLCD.setColor(255, 255, 255);
  myGLCD.print("BLASMA", 190, 130);

  myGLCD.setColor(0, 200, 0);
  myGLCD.fillRoundRect (10, 173, 150, 221);
  myGLCD.setColor(255, 255, 255);
  myGLCD.drawRoundRect (10, 173, 150, 221);
  myGLCD.setBackColor(0, 200, 0);
  myGLCD.setColor(255, 255, 255);
  myGLCD.print("GRASMA", 30, 190);

  myGLCD.setColor(200, 0, 200);
  myGLCD.fillRoundRect (170, 173, 310, 221);
  myGLCD.setColor(225, 255, 255);
  myGLCD.drawRoundRect (170, 173, 310, 221);
  myGLCD.setBackColor(200, 0, 200);
  myGLCD.setColor(255, 255, 255);
  myGLCD.print("SPASMA", 190, 190);

}


//===drawSoundControl Page====

void drawSoundControl() {

  myGLCD.setColor(100, 155, 203);
  myGLCD.fillRoundRect (10, 10, 60, 36);
  myGLCD.setColor(255, 255, 255);
  myGLCD.drawRoundRect (10, 10, 60, 36);
  myGLCD.setFont(BigFont);
  myGLCD.setBackColor(100, 155, 203);
  myGLCD.print("<-", 18, 15);
  myGLCD.setBackColor(0, 0, 0);
  myGLCD.setFont(SmallFont);
  myGLCD.print("MAIN MENU", 70, 18);


  // forward to shutdown
  myGLCD.setColor(100, 155, 203);
  myGLCD.fillRoundRect (258, 10, 308, 36);
  myGLCD.setColor(255, 255, 255);
  myGLCD.drawRoundRect (258, 10, 308, 36);
  myGLCD.setBackColor(100, 155, 203);
  myGLCD.setFont(BigFont);
  myGLCD.print("->", 266, 15);
  myGLCD.setFont(SmallFont);
  myGLCD.setBackColor(0, 0, 0);
  myGLCD.print("SHUTDOWN", 185, 18);

  myGLCD.setFont(BigFont);
  myGLCD.print("SOUND LEVEL CONTROL:", 10, 75);
  myGLCD.print("V", 10, 135);

  myGLCD.setColor(255, 255, 255);
  myGLCD.drawRect(30, 130, 310, 160); // R - Slider

  //volume box bottom right
  myGLCD.setColor(200, 0, 200);
  myGLCD.fillRoundRect (170, 173, 250, 230);
  myGLCD.setColor(225, 255, 255);
  myGLCD.drawRoundRect (170, 173, 250, 230);
  myGLCD.setBackColor(200, 0, 200);

  //volume level directions
  myGLCD.setBackColor(0, 0, 0);
  myGLCD.setFont(BigFont);
  myGLCD.setColor(225, 255, 255);
  myGLCD.print("TOUCH FOR", 10, 180);
  myGLCD.print("CURRENT V", 10, 200);
}



// ====Draw Plasa Volume Page====

void drawPlasmaVolume() {

  //return button
  myGLCD.setColor(100, 155, 203);
  myGLCD.fillRoundRect (10, 10, 60, 36);
  myGLCD.setColor(255, 255, 255);
  myGLCD.drawRoundRect (10, 10, 60, 36);
  myGLCD.setFont(BigFont);
  myGLCD.setBackColor(100, 155, 203);
  myGLCD.print("<-", 18, 15);
  myGLCD.setBackColor(0, 0, 0);
  myGLCD.setFont(SmallFont);
  myGLCD.print("MAIN MENU", 70, 10);

  // forward button to infographixs page
  myGLCD.setColor(100, 155, 203);
  myGLCD.fillRoundRect (258, 10, 308, 36);
  myGLCD.setColor(255, 255, 255);
  myGLCD.drawRoundRect (258, 10, 308, 36);
  myGLCD.setFont(BigFont);
  myGLCD.setBackColor(100, 155, 203);
  myGLCD.print("->", 266, 15);
  myGLCD.setFont(SmallFont);
  myGLCD.setBackColor(0, 0, 0);
  myGLCD.print("INFOGRAPHIXS", 152, 28);

  myGLCD.setFont(BigFont);
  myGLCD.setBackColor(0, 0, 0);
  myGLCD.print("PLASMA VOLUME GUI", CENTER, 50);
  myGLCD.setFont(SmallFont);
  myGLCD.print("Adjust for plasma output volume", CENTER, 70);
  myGLCD.print("and force by controlling ducted fan", CENTER, 80);

  myGLCD.setColor(0, 0, 200);
  myGLCD.fillRoundRect (10, 115, 150, 163);
  myGLCD.setColor(225, 255, 255);
  myGLCD.drawRoundRect (10, 115, 150, 163);
  myGLCD.setBackColor(0, 0, 200);
  myGLCD.setColor(255, 255, 255);
  myGLCD.setFont(BigFont);
  myGLCD.print("DECREASE", 20, 130);

  myGLCD.setColor(200, 0, 0);
  myGLCD.fillRoundRect (170, 115, 310, 163);
  myGLCD.setColor(225, 255, 255);
  myGLCD.drawRoundRect (170, 115, 310, 163);
  myGLCD.setBackColor(200, 0, 0);
  myGLCD.setColor(255, 255, 255);
  myGLCD.print("INCREASE", 180, 130);

  //Plasma volume  box bottom right
  myGLCD.setColor(200, 0, 200);
  myGLCD.fillRoundRect (170, 173, 250, 230);
  myGLCD.setColor(225, 255, 255);
  myGLCD.drawRoundRect (170, 173, 250, 230);
  myGLCD.setBackColor(200, 0, 200);

  //Plasma volume directions
  myGLCD.setBackColor(0, 0, 0);
  myGLCD.setFont(BigFont);
  myGLCD.setColor(225, 255, 255);
  myGLCD.print("CURRENT", 20, 180);
  myGLCD.print("PLASMA", 25, 200);
  myGLCD.print("VOLUME", 23, 220);
}


//====draws plasmaBrightness page====
//pixie brightness

void  drawPlasmaBrightness() {

  //return button
  myGLCD.setColor(100, 155, 203);
  myGLCD.fillRoundRect (10, 10, 60, 36);
  myGLCD.setColor(255, 255, 255);
  myGLCD.drawRoundRect (10, 10, 60, 36);
  myGLCD.setFont(BigFont);
  myGLCD.setBackColor(100, 155, 203);
  myGLCD.print("<-", 18, 15);
  myGLCD.setBackColor(0, 0, 0);
  myGLCD.setFont(SmallFont);
  myGLCD.print("BACK", 70, 18);

  myGLCD.setFont(BigFont);
  myGLCD.print("PIXIE BRIGHTNESS", CENTER, 50);
  myGLCD.setFont(SmallFont);
  myGLCD.print("Adjust for pixie brightness", CENTER, 70);
  myGLCD.print("MIN/MAX mapped 10-250", CENTER, 90);

  myGLCD.setColor(0, 0, 200);
  myGLCD.fillRoundRect (10, 115, 150, 163);
  myGLCD.setColor(225, 255, 255);
  myGLCD.drawRoundRect (10, 115, 150, 163);
  myGLCD.setBackColor(0, 0, 200);
  myGLCD.setColor(255, 255, 255);
  myGLCD.setFont(BigFont);
  myGLCD.print("DECREASE", 20, 130);

  myGLCD.setColor(200, 0, 0);
  myGLCD.fillRoundRect (170, 115, 310, 163);
  myGLCD.setColor(225, 255, 255);
  myGLCD.drawRoundRect (170, 115, 310, 163);
  myGLCD.setBackColor(200, 0, 0);
  myGLCD.setColor(255, 255, 255);
  myGLCD.print("INCREASE", 180, 130);

  //Plasma number box
  myGLCD.setColor(200, 0, 200);
  myGLCD.fillRoundRect (170, 173, 250, 230);
  myGLCD.setColor(225, 255, 255);
  myGLCD.drawRoundRect (170, 173, 250, 230);
  myGLCD.setBackColor(200, 0, 200);

  //Plasma  directions
  myGLCD.setBackColor(0, 0, 0);
  myGLCD.setFont(BigFont);
  myGLCD.setColor(225, 255, 255);
  myGLCD.print("CURRENT", 20, 180);
  myGLCD.print("PIXIE", 35, 200);
  myGLCD.print("BRIGHTNESS", 5, 220);
}

//====Draw infographixs Page + back button======
// ====== AND draws bitmap====

void drawInfographixsBack() {

  //draw this first so button can overlay
  myGLCD.drawBitmap (20, 31, 280, 178, engsml);

  //draws back button
  myGLCD.setColor(100, 155, 203);
  myGLCD.fillRoundRect (10, 10, 60, 36);
  myGLCD.setColor(255, 255, 255);
  myGLCD.drawRoundRect (10, 10, 60, 36);
  myGLCD.setFont(BigFont);
  myGLCD.setBackColor(100, 155, 203);
  myGLCD.print("<-", 18, 15);
  myGLCD.setBackColor(0, 0, 0);
  myGLCD.setFont(SmallFont);
  myGLCD.print("PLASMA VOLUME", 70, 10);

  myGLCD.print("PLASMA ENGINE", 165, 170);
  myGLCD.print("DETAIL", 185, 190);
}

//======================================
//====shutdown functions and Screens====
//======================================

void  drawShutdownScreen() {

  myGLCD.drawRoundRect (1, 1, 318, 238);
  myGLCD.setColor(255, 255, 255); // Sets color to white
  myGLCD.setFont(BigFont); // Sets font to big
  myGLCD.setBackColor(0, 0, 0);
  myGLCD.print("ENGINE SHUTDOWN", CENTER, 10); // Prints the string on the screen
  myGLCD.print("PRESS TO INITIATE", CENTER, 45); // Prints the string  myGLCD.setFont(DotMatrix_M_Slash);


  // Button - <- MAIN MENU
  myGLCD.setColor(200, 200, 0); // Sets  color
  myGLCD.fillRoundRect (35, 90, 285, 130); // Draws filled rounded rectangle
  myGLCD.setColor(255, 255, 255); // Sets color to white
  myGLCD.drawRoundRect (35, 90, 285, 130); // Draws rounded rectangle without a fill, so the overall appearance of the button looks like it has a frame
  myGLCD.setFont(BigFont); // Sets the font to big
  myGLCD.setBackColor(200, 200, 0 ); // Sets the background color of the area where the text will be printed to green, same as the button
  myGLCD.print("<-MAIN MENU", CENTER, 102); // Prints the string

  // Button -  SHUTDOWN
  myGLCD.setColor(255, 0, 0); //(228,7,215);
  myGLCD.fillRoundRect (35, 140, 285, 180);
  myGLCD.setColor(255, 255, 255);
  myGLCD.drawRoundRect (35, 140, 285, 180);
  myGLCD.setFont(BigFont);
  myGLCD.setBackColor(255, 0, 0); //(228,7,215);
  myGLCD.print("SHUTDOWN", CENTER, 152);
}


void  drawPowerDown() {
  myGLCD.clrScr();
  myGLCD.setColor(255, 0, 0); // Sets color to white
  myGLCD.drawRoundRect (60, 28, 255, 80);
  myGLCD.drawRoundRect (50, 18, 265, 90);
  myGLCD.setFont(GroteskBold24x48);
  myGLCD.setBackColor(0, 0, 0);
  myGLCD.print("WARNING", CENTER, 30);
  myGLCD.setFont(BigFont);
  myGLCD.setColor(255, 255, 255);
  myGLCD.print("POWERING DOWN", CENTER, 115);
  for (int p = 0; p < numLedPins; p++) {
    digitalWrite(ledPins[p], HIGH);
    delay(200);
    digitalWrite(ledPins[p], LOW);
    delay(200);
  }
}




void  drawOffScreen() {
  myGLCD.clrScr();
  myGLCD.setColor(255, 255, 255); // Sets color to white
  myGLCD.drawRoundRect (1, 1, 318, 238);

  for (int i = 0  ; i < 3 ; i++) {
    myGLCD.setColor(255, 255, 255); // Sets color to white
    myGLCD.setFont(BigFont); // Sets font to big
    myGLCD.setBackColor(0, 0, 0);
    myGLCD.print("TURN OFF", CENTER, 90);
    myGLCD.print("POWER SWITCH", CENTER, 120);
    delay(300);

    myGLCD.setColor(0, 0, 0); // Sets color to black
    myGLCD.setFont(BigFont); // Sets font to big
    myGLCD.setBackColor(0, 0, 0);
    myGLCD.print("TURN OFF", CENTER, 90);
    myGLCD.print("POWER SWITCH", CENTER, 120);
    delay(300);
  }

  myGLCD.setColor(255, 255, 255); // Sets color to white
  myGLCD.drawRoundRect (1, 1, 318, 238);
  myGLCD.setFont(GroteskBold24x48);
  myGLCD.setBackColor(0, 0, 0);
  myGLCD.print("TURN OFF", CENTER, 50);
  myGLCD.print("POWER SWITCH", CENTER, 120);
}




//=================================================
//====== Custom Touch Control functions ===========
//=================================================


//======= Sound Level Touch Settings ======

void setSoundLevel() {
  if (myTouch.dataAvailable()) {
    myTouch.read();
    x = myTouch.getX();
    y = myTouch.getY();
    // Area of the Red color slider
    if ( (y >= 130) && (y <= 160)) {
      xR = x; // Stores the X value where the screen has been pressed in to variable xR
      if (xR <= 40) { // Confines the area of the slider to be above 40 pixels
        xR = 40;
      }
      if (xR >= 300) { /// Confines the area of the slider to be under 300 pixels
        xR = 300;
      }
    }


    // Maps the values of the X - Axis from 38 to 0 and 300 to 40 for volume settings
    uint16_t xRC = map(xR, 40, 300, 10, 60);  // you can set 'out' to 0, 40 if you want less volume and range


    Serial.print("Setting volume to ");
    Serial.println(xRC);
    Wire.beginTransmission(MAX9744_I2CADDR);
    Wire.write(xRC);
    delay(10);
    Wire.endTransmission(MAX9744_I2CADDR);

    // Draws the positioner
    myGLCD.setColor(0, 255, 0);
    myGLCD.fillRect(xR, 135, (xR + 4), 155); // Positioner
    myGLCD.setColor(255, 0, 0);
    myGLCD.fillRect(31, 135, (xR - 1), 155);
    myGLCD.setColor(0, 0, 0);
    myGLCD.fillRect((xR + 5), 135, 309, 155);

    myGLCD.setBackColor(200, 0, 200);
    myGLCD.setFont(BigFont);
    myGLCD.setColor(255, 255, 255);
    myGLCD.print(xRC, 190, 195);


    if ((x >= 31) && (x <= 309) && (y >= 135) && (y <= 155)) {
      if (musicPlayer.stopped()) {
        musicPlayer.softReset();
        musicPlayer.startPlayingFile("BUTTON.WAV");
      }
    }
    if ((x >= 170) && (x <= 250) && (y >= 173) && (y <= 230)) {
      drawFrame(170, 173, 250, 230);
    }
  }
}



//======Plasma Volume touch settings ============

void setPlasmaVolume() {

  turboPWM = map(iV, 0, 9, turboMin, turboMax);

  turboVolumeRange = iV;





  myGLCD.setBackColor(200, 0, 200);
  myGLCD.setColor(0, 255, 0);
  myGLCD.setFont(SevenSegNumFont);
  myGLCD.print(iV, 193, 177);



  switch (turboVolumeRange) {

    case 0:
      myGLCD.setColor(0, 0  , 255);
      myGLCD.fillCircle (280, 200, 20);
      break;

    case 1:
      myGLCD.setColor(0, 0  , 255);
      myGLCD.fillCircle (280, 200, 20);
      break;

    case 2:
      myGLCD.setColor(0, 100  , 200);
      myGLCD.fillCircle (280, 200, 20);
      break;

    case 3:
      myGLCD.setColor(0, 150 , 0);
      myGLCD.fillCircle (280, 200, 20);
      break;

    case 4:
      myGLCD.setColor(0, 255  , 0);
      myGLCD.fillCircle (280, 200, 20);
      break;

    case 5:
      myGLCD.setColor(0, 255  , 0);
      myGLCD.fillCircle (280, 200, 20);
      break;

    case 6:
      myGLCD.setColor(100, 150  , 0);
      myGLCD.fillCircle (280, 200, 20);
      break;

    case 7:
      myGLCD.setColor(200, 0  , 0);
      myGLCD.fillCircle (280, 200, 20);
      break;

    case 8:
      myGLCD.setColor(255, 0  , 0);
      myGLCD.fillCircle (280, 200, 20);
      break;

    case 9:
      myGLCD.setColor(255, 0  , 0);
      myGLCD.fillCircle (280, 200, 20);
      break;
  }

  if (iV == 0) {
    myGLCD.setBackColor(0, 0  , 255);
    myGLCD.setFont(SmallFont);
    myGLCD.setColor(255, 255, 255);
    myGLCD.print("OFF", 270, 195);
  }

  if (iV == 9) {
    myGLCD.setBackColor(255, 0  , 0);
    myGLCD.setFont(SmallFont);
    myGLCD.setColor(255, 255, 255);
    myGLCD.print("MAX", 270, 195);
  }
  servo1.write( turboPWM );
  Serial.print("Setting turbo to ");
  Serial.println(turboPWM);
}


//======Pixie Brightness touch settings ==========
// this will adjust the pixie brightness

void setPixieBrightness() {

  int pixieLevel = map(iP, 0, 9, pixieMin, pixieMax);
  pixieBrightnessRange = iP;

  myGLCD.setBackColor(200, 0, 200);
  myGLCD.setColor(0, 255, 0);
  myGLCD.setFont(SevenSegNumFont);
  myGLCD.print(iP, 193, 177);

  Serial.print("pixieBrightnessRange = ");
  Serial.println(pixieBrightnessRange);
  Serial.print("Setting Pixie to ");
  Serial.println( pixieLevel);

  switch (pixieBrightnessRange) {

    case 0:
      myGLCD.setColor(0, 0  , 255);
      myGLCD.fillCircle (280, 200, 20);
      break;

    case 1:
      myGLCD.setColor(0, 0  , 255);
      myGLCD.fillCircle (280, 200, 20);
      break;

    case 2:
      myGLCD.setColor(0, 100  , 200);
      myGLCD.fillCircle (280, 200, 20);
      break;

    case 3:
      myGLCD.setColor(0, 150 , 0);
      myGLCD.fillCircle (280, 200, 20);
      break;

    case 4:
      myGLCD.setColor(0, 255  , 0);
      myGLCD.fillCircle (280, 200, 20);
      break;

    case 5:
      myGLCD.setColor(0, 255  , 0);
      myGLCD.fillCircle (280, 200, 20);
      break;

    case 6:
      myGLCD.setColor(100, 150  , 0);
      myGLCD.fillCircle (280, 200, 20);
      break;

    case 7:
      myGLCD.setColor(200, 0  , 0);
      myGLCD.fillCircle (280, 200, 20);
      break;

    case 8:
      myGLCD.setColor(255, 0  , 0);
      myGLCD.fillCircle (280, 200, 20);
      break;

    case 9:
      myGLCD.setColor(255, 0  , 0);
      myGLCD.fillCircle (280, 200, 20);
      break;
  }

  if (iP == 0) {
    myGLCD.setBackColor(0, 0  , 255);
    myGLCD.setFont(SmallFont);
    myGLCD.setColor(255, 255, 255);
    myGLCD.print("MIN", 270, 195);
  }

  if (iP == 9) {
    myGLCD.setBackColor(255, 0  , 0);
    myGLCD.setFont(SmallFont);
    myGLCD.setColor(255, 255, 255);
    myGLCD.print("MAX", 270, 195);
  }
  strip.setBrightness(pixieLevel);
}



//=================================================
//====== Special PIXIE LED Plasma functions  ======
//=================================================
// this will adjust the pixie display

void neopixelShow() {  //it's really a PIXIE show...

  int i = random(30);// random delay

  if (selectLED == '0' ) {
    colorWipe(strip.Color (255 , 0, 0), i);  // red
    colorWipe(strip.Color (255 , 150, 0), i); //orange
    colorWipe(strip.Color (250 , 150, 0), i); //yellow
  }

  if (selectLED == '1') {
    colorWipe(strip.Color (0 , 0, 255), i);  // blue
    colorWipe(strip.Color (0 , 100, 200), i);
    colorWipe(strip.Color (80 , 0, 200), i);
  }

  if (selectLED == '2') {
    colorWipe(strip.Color (0 , 255, 0), i);  // green
    colorWipe(strip.Color (0 , 200, 0), i);
    colorWipe(strip.Color (120 , 255, 0), i);
  }

  if (selectLED == '3') {
    flashyRandom(5, 3);  // first number is 'wait' delay, shorter num == shorter twinkle
    // second number is how many neopixels to light up
  }
}


void plasmaWindowShow() {
  if (selectLED == '0') { //RASMA
    digitalWrite(RASMABUTTON, HIGH);
    digitalWrite(BLASMABUTTON, LOW);
    digitalWrite(GRASMABUTTON, LOW);
    digitalWrite(SPASMABUTTON, LOW);
  }
  if (selectLED == '1') {//BLASMA
    digitalWrite(RASMABUTTON, LOW);
    digitalWrite(BLASMABUTTON, HIGH);
    digitalWrite(GRASMABUTTON, LOW);
    digitalWrite(SPASMABUTTON, LOW);
  }
  if (selectLED == '2') {//GRASMA
    digitalWrite(RASMABUTTON, LOW);
    digitalWrite(BLASMABUTTON, LOW);
    digitalWrite(GRASMABUTTON, HIGH);
    digitalWrite(SPASMABUTTON, LOW);
  }
  if (selectLED == '3') {//SPASMA
    digitalWrite(RASMABUTTON, LOW);
    digitalWrite(BLASMABUTTON, LOW);
    digitalWrite(GRASMABUTTON, LOW);
    digitalWrite(SPASMABUTTON, HIGH);
  }
}


// Fills Pixies one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
  for (uint16_t i = 0; i < strip.numPixels(); i++) {
    strip.setPixelColor(i, c);
    strip.show();
    delay(wait);
  }
}

// for 'random' pixie action
void flashyRandom(int wait, uint8_t howmany) {

  for (uint16_t i = 0; i < howmany; i++) {
    int c = random(MYCOLORS);
    int red =  myColors[c][2];// pick any color off array myColors, put into []
    int green =  myColors[c][5];
    int blue =  myColors[c][6];

    // get a random pixel from the list
    int j = random(strip.numPixels());
    //Serial.print("Lighting up "); Serial.println(j);

    //now we will 'fade in' only (to save time because only 3 pixies)
    for (int x = 0; x < 3; x++) {
      int r = red * (x + 1); r /= 5;
      int g = green * (x + 1); g /= 5;
      int b = blue * (x + 1); b /= 5;

      strip.setPixelColor(j, strip.Color(r, g, b));
      strip.show();
      delay(wait);
    }
  }
}


// File listing helper for SD audio files
void printDirectory(File dir, int numTabs) {
  while (true) {

    File entry =  dir.openNextFile();
    if (! entry) {
      // no more files
      //Serial.println("**nomorefiles**");
      break;
    }
    for (uint8_t i = 0; i < numTabs; i++) {
      Serial.print('\t');
    }
    Serial.print(entry.name());
    if (entry.isDirectory()) {
      Serial.println("/");
      printDirectory(entry, numTabs + 1);
    } else {
      // files have sizes, directories do not
      Serial.print("\t\t");
      Serial.println(entry.size(), DEC);
    }
    entry.close();
  }
}
Attachments
Pip Boy face plate off thingiverse and scaled to my TFT
Pip Boy face plate off thingiverse and scaled to my TFT
IMG_2823.JPG (134.57 KiB) Viewed 350 times
Last edited by XRAD on Wed Mar 20, 2019 8:02 pm, edited 52 times in total.

User avatar
XRAD
 
Posts: 754
Joined: Sat Nov 19, 2016 3:28 pm

Re: XRAD'S PLASMA ENGINE

Post by XRAD »

Does anyone have a command line to get the Music Maker feather to 'loop play ' (like HOLD on the FX board) a track?

I have tried many variations of state change and other ideas, but they do not work. I looked through the github lib and code for the Music Maker Feather and shield, no luck. Play/Pause/stop/playtrack/playfullfile are all there. Also, on the vs1053 data sheet, there is fast forward and fast rewind. But No loop or hold or repeat last track anywhere......

If there is no command for this, can admin point me in the right direction. I am sure that many of us using the Music maker could use this option.

like here in the prop python code:
https://learn.adafruit.com/lightsaber-f ... g/software

Code: Select all


 if mode == 0:                       # If currently off...
            enable.value = True
            power('on', 1.7, False)         # Power up!
            play_wav('idle', loop=True)     # Play background hum sound
            mode = 1     
     
I can get a loop to play endlessly without issue using:

Code: Select all


void playBackground () {
  if (musicPlayer.stopped()) { // && (humState == 0)) {  
    musicPlayer.startPlayingFile("HUM.WAV");   
  }
  playBackground ();
}

BUT, I can't stop it once started. I just need a simple way to interrupt this loop.

Locked
Please be positive and constructive with your questions and comments.

Return to “Feather - Adafruit's lightweight platform”