FX Light Code

 //////////////////////////////////////START OF CODE


//FX Light Mod
//V2
//for Digimon 20th and Digimon X

//Code Ver 6.1
//Sept 15, 2023
//Joe V.

//Mod Highlights
//EZ DIY MOD CHIP
//C-Button Operation
//Lighting FX synced to Digimon Audio
//5 Different Brightness Modes for backlight
//3 Different Modes for Sound FX
//3 Colour Backlight FX
//No screen flicker
//No addition batteries
//Screen Time-out, Auto Light Off
//Minimal Current Draw
//Adaptable to all Digimon 20th, and Digmon X

//ABOUT ATTINYS, GETTING THE RIGHT ONE
//25,45,85 ONLY MEANS PROGRAM MEMORY AND DYNAMIC VARIABLE SIZE
//V LOWS THE MAX FREQUENCY OF OSCILLATOR, FROM 20MHZ TO 10MHZ, BUT ALLOWS FOR 1.8V INSTEAD OF 3V
//SU IS 8-SOIC 5.3mm wide  <-- physical size*** used in MOD PCB
//SSU IS 8-SOIC 3.9mm wide <-- Physical size options
//PU IS 8-DIP <-- too big
//R is irrelevent as it is for dispensing type meaning Real

//ATTiny25V10SU
//Specs
//1.8V ~ 5.5V
//6 I/Os
//Core Size - 8 bit
//Memory 8kb (4k x 16)
//EEPROM 512 x 8
//RAM 512 x 8
//Speed up to 10Mhz
//Oscillator - Internal

//Function
//"Digimon Screen On" signal turns on ATTiny through N-CH MOSFET, and sets white backlight to off,
//and sound setting to red.
//ATTiny Idles waiting for Signal from C-Button of either:
//1.  Holding C-Button for 1 Second will advance brightness through 5 intensities, 6 time back to off. Loop. Default is off when screen comes on.
//2.  Rapidly Tapping C-Button 8 times will advance the sound setting. Default is Red On when screen comes on. Setting 2 is Red OFF. Setting 3 is Ignore Sound SIgnal. Loop.

//Once Backlight is on it stays on until either:
//1. Digimon Screen off signals MCP1640 to turn off power to ATTiny
//2. Double Tap C-Button, Followed By Holding C-Button 1 Second
//3. Hold Digimon Bottom Button and cycle through brightness setting until in the OFF setting

//Battery Supply is CR2032 - 3V - 235mAh
//Power Usuage
//Digimon Idle Power (Screen Off) - 50uA            - 4,700 Hours   ~ 28 Weeks
//Digimon Working Power 1mA (Screen On)             - 235 Hours       ~ 10 Days       of Idle Screen Time
//Digimon Woring Power Max 4mA (Screen Updating)    - 58.75 Hours       ~ 2 Days      of Actions Screen Time
//    +
//IC Off - Screen off ~ 0.7 uA               - 335,714 Hours ~ 38.3 Years
//IC On - Screen on ~ 1.54 mA                 - 153 Hours     ~ 6.4 Days   of Screen on Time
//IC On with LED On ~ 5 mA                        - 47 Hours    ~ 6.5 Day of Light
//IC On with LED On ~ 10 mA                         - 23.5 Hours    ~ 1.96 Days of Light
//IC On with LED On ~ 15 mA                        - 15.67 Hours    ~ 1 Day of Light
//Max LED current ~ 20mA                            - 11.75 Hours of Light

//ATTiny
//Pin 1 Reset + Pin 8 VCC + MCP1640 3.3V Output
//Pin 2 Button Signal + Digimon DTR Data (Yellow wire)
//Pin 3 Blank
//Pin 4 GND
//Pin 5 PWM0 -> Resistor SMD -> FX LED Anode Positive Long Lead
//Pin 6 PWM1 -> Resistor SMD -> BackLight LED Anode Positive Long Lead
//Pin 7 Signal -> Capacitor SMD 10nF - > Digimon Buzz Neg - (Green wire)

//Recommend Resistors for 5mA 2V LEDs Red, Yellow, Oragne, Green
//each gets a 200ohm
//Recommend Resistors for 5mA 3V LEDs Blue
//each gets a 100ohm

//Programming IC instruction
//Internal Clock set to 1Mhz for Power Saving <--- Must do to preserve battery
//Processor ATTiny
//Arduino as ISP
//Burn BOOTLOADER to ATTiny - Using an arduino set-up already as an ISP connected to chip through DIY programmer
//Then Upload Program - Using an arduino set-up already as an ISP connected to chip through DIY programmer - Click Upload with Programmer, not upload
//Upload the Clock Frequency Test Sketch, and test for 1MHz Clock Set
//Then Upload LED Program - Using an arduino set-up already as an ISP connected to chip through DIY programmer - Click Upload with Programmer, not upload

//Sketch Size on all ICs
//Program Storage - 1910 bytes
//Global Variables - 34 bytes

//ATTiny85 - Flash Memory 8192 bytes, SRAM 512 bytes
//Program Storage Used - 23%
//Dynamic Memory Used - 6%

//ATTiny45 - Flash Memory 4096 bytes, SRAM 256 bytes
//Program Storage Used - 46%
//Dynamic Memory Used - 13%

//Attiny25 - Flash Memory 2048 bytes, SRAM 128 bytes
//Program Storage Used - 93%
//Dynamic Memory Used - 26%

//Pin Locations
#define LED 1 //ATTiny Pin 6 - 100-200 Ohm Resistor - LED Anode Positive Long Lead
#define ButtonSignal 3 //ATTiny Pin 2 - Digimon DTR Data
#define BuzzerSignal 2 //Attiny Pin 7 - Digimon BUZZ +
#define LEDX 0 //Attiny Pin 5 - 100-200 Ohm Resistor - LED Anode Postive Long Lead
//Global variables

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Defaults that could be changed before Programming IC as prefered
//These will be the preset everytime the Digimon screen comes on
int RedState = 1;      // Sketch Default is 1, set for Red Sound FX. Used to Set differnt Sound Operation. 0 ignore sound signal, 1 is red signal for buzzer (Default), 2 is just flash for buzzer
int LEDState = 0;      // Sketch Default is 0, set the default Backlight function for when the Digimon Screen turns on. Used to set different brightness on/off setting. 0 for OFF (Default) and 1 - 5 for BackLight
#define TAPSETAMOUNT 8      //The amount of C-Button Taps Before FX Change
#define TAPOFFSET 2         //The amount of C-Button Taps plus a final Hold for instant backlight OFF
#define HELDSETAMOUNT 1000  //Time in millis C-button is pushed for backlight 1000ms = 1sec
#define LevelOff 0    //0%
#define Level1 51      //20% duty cycle
#define Level2 89      //35% duty cycle
#define Level3 128     //50% duty cycle
#define Level4 166     //65% duty cycle
#define Level5 204     //80% duty cycle
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// Variables will change:
int TAP = 0;            //count how many taps on button
int SoundFreq = 0;      //count the ups, and then downs, for a small sample period
int SoundFreqReal = 0;   //count the current sound frequency recieved

bool SignalReadButton;  //used to read the C-button signal and hold its value throughout the loop
bool TapCheck = false;       //used to make sure its tap, not a hold
bool SignalReadBuzzer;  //used to read the Buzzer signal and hold its value throughout the loop
bool lastSignalReadBuzzer = false;  //used to help determine change in buzzer voltage, slope detection, to help count audio frequency

// the following variables are unsigned longs because the time, measured in
// milliseconds, will quickly become a bigger number than can be stored in an int.
unsigned long Timer = 0;  // the last time the output pin was toggled
unsigned long Timer2 = 0;  // the last time the output pin was toggled
unsigned long Count = HELDSETAMOUNT;    // Timer that is Counted for LED on time            500ms = Half sec
unsigned long Count2 = 200;    // Timer that is Counted for LED Tapping    200ms = One Fifth sec
unsigned long samplesize = 10; //Time used to sample the sound signal
unsigned long previousCountSoundMillis = 0;   //timer used for the sound signal frequency measurements
unsigned long Debounce = 50;  //used to prevent multiple unwanted presses of C-button

void setup() {
  // put your setup code here, to run once:

pinMode(LED,OUTPUT); //set white light LED OUTPUT
pinMode(LEDX,OUTPUT);  //Set LED to run on buzzer signals, recommend red
pinMode(ButtonSignal,INPUT); //Set Button Input
pinMode(BuzzerSignal,INPUT); //Set Buzzer Sound Input
}

void loop() {
  //Code Loop, Main Program

SignalReadButton = digitalRead(ButtonSignal); //Read the Digimon Button for it being pushed

  if (SignalReadButton == true) {      //WHEN BUTTON PRESSED
 
      if (TapCheck == false){
        TapCheck = true;
        TAP++;
      }
if (((millis() - Timer) >= Count) and (TAP > TAPOFFSET)) {  //is yes then Check if Signal is recieved Long Enough
        LEDState = 0;
        Timer = millis();  //and Reset Timer to count again from this moment
} else if (((millis() - Timer) >= Count) and (TAP < TAPOFFSET)) {  //is yes then Check if Signal is recieved Long Enough
        LEDState++;
        if (LEDState >= 6) {LEDState = 0;}    //if yes then Set LED on
        Timer = millis();  //and Reset Timer to count again from this moment
      }

    Timer2 = millis(); //SET TIMER 2 TO LAST TIME BUTTON PRESSED
  }
 
  if (SignalReadButton == false) {     //WHEN BUTTON NOT PRESSED

    if ((millis() - Timer2) >= Count2) {  //is yes then Check if Signal is recieved Long Enough
      TAP = 0;
    }

    if ((millis() - Timer2) >= Debounce) {  //is yes then Check if Signal is recieved Long Enough
      TapCheck = false;         //ALLOW ANOTHER TAP TO BE COUNTED
    }
 
  Timer = millis();     //SET TIMER TO LAST TIME BUTTON NOT PRESSED
  }

  if (TAP >= TAPSETAMOUNT) {
    RedState++;

    //Show a signal of change
    analogWrite(LED,LevelOff);
    analogWrite(LEDX,LevelOff);
    delay(100);
    analogWrite(LEDX,Level1);
    delay(100);
    analogWrite(LEDX,LevelOff);
    delay(100);
    analogWrite(LED,Level1);
    delay(100);
    analogWrite(LED,LevelOff);
    delay(100);
    analogWrite(LEDX,Level1);
    delay(100);
    analogWrite(LEDX,LevelOff);
    delay(100);

    if (RedState >= 3) {
      RedState = 0;
    }

if (RedState == 1) {
    analogWrite(LED,LevelOff);           //Red Light so Default
    analogWrite(LEDX,Level1);
    delay(1000);
    } else if (RedState == 2) {
      if (LEDState >= 1) {
        analogWrite(LED,LevelOff);
      } else {
        analogWrite(LED,Level1);
      }
    analogWrite(LEDX,LevelOff);  
    delay(1000);
    } else if (RedState == 0) {
    }
    analogWrite(LED,LevelOff);
    analogWrite(LEDX,LevelOff);

    TAP = 0;
    }

SignalReadBuzzer = digitalRead(BuzzerSignal); //Read the Digimon Buzzer for sound signal

if (SignalReadBuzzer != lastSignalReadBuzzer) {   //if sound signal has gone from low to high or high to low (a slope), add 1 to counter
 SoundFreq++;
 lastSignalReadBuzzer = SignalReadBuzzer;
}

  if (millis() - previousCountSoundMillis >= samplesize) {  //use one-hundredth of a second for the sampling rate
    previousCountSoundMillis += samplesize;                //reset the sample counter
    SoundFreqReal = SoundFreq * (500 / samplesize);       //calculate counted slopes over sample size period to get sound signal frequency
    SoundFreq = 0;                                       //reset slope counter
  }

if (SoundFreqReal > 50 and RedState > 0) {   //check for sound signal, check for output of sound selection on
    if (LEDState > 0) {  //check if backlight is on
      analogWrite(LED,LevelOff);  //flashing off backlight with sound
      if (RedState == 1) {    //check if red is selected
        analogWrite(LEDX,Level2);   //turn on red
      } else {
        analogWrite(LEDX,LevelOff); //turn off red
      }
    }
    else { //if backlight is off
    if (RedState == 1) { //check if Red light is selected
      analogWrite(LEDX,Level3);  //flash red light with sound
      analogWrite(LED,LevelOff);  //keep white off
    }
    else {
    analogWrite(LED,Level3);  //flash white light with sound
    analogWrite(LEDX,LevelOff);   //keep red off
    }
    }

  }

  else
 
  {
  if (LEDState == 1) {analogWrite(LED,Level1);} //min brightness 51 duty cycle of 20%
  if (LEDState == 2) {analogWrite(LED,Level2);} //2nd stage brightness duty cycle of 35%
  if (LEDState == 3) {analogWrite(LED,Level3);} //3rd brightness duty on cycle of 50%
  if (LEDState == 4) {analogWrite(LED,Level4);} //4th brightness duty cycle of 65%
  if (LEDState == 5) {analogWrite(LED,Level5);} //max brightness 204 duty cycle of 80%
  if (LEDState == 0) {analogWrite(LED,LevelOff);}   //off
  analogWrite(LEDX,LevelOff); //keep Red LED off
}

}

//////////////////////////////////////END OF CODE

No comments:

Post a Comment

Please Leave Your Reviews: