Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <EEPROM.h>
- #include <avr/sleep.h>
- #include <avr/power.h>
- int PWMPin = 0;
- int potPin = A3;
- int potValue;
- int switchPin = 2;
- int LEDPin = 1;
- int voltPin = A2;
- int switchPinState;
- int lastSwitchState = LOW;
- float PWMOutputValue = 0;
- float uBatt;//unloaded battery voltage
- int battAnalog;
- int analogAverage1;
- int analogAverage2;
- int analogAverage3;
- int analogAverage4;
- float lBatt;//loaded battery voltage
- int inputMode;//2 for 2s, 3 for 3s, 4 for 4s
- float uBattMin;
- float lBattMin;
- float lowBattVoltage;
- int outputMode; // 0 for unregulated 1 for regulated
- int LVCMode; // 0 for LiOn 1 for LiPo
- int deadBattFlag; // flag for low(dead) unloaded voltage
- int lowBattFlag; // flag for low battery
- long lowBattBlinkTimer; //timer for low batt blink
- int lowBattBlinkTime = 1000;
- int lowBattBlinkState = LOW;
- unsigned long sleepTimer = 0;
- float vRMS;
- float dutyCycle;
- long lockTimer = 0;
- long fireTimer = 0;
- long holdTimer = 0;
- byte fireFlag = 0;
- byte lockFlag = 0;
- byte readFlag = 0;
- byte switchClicks = 0;
- byte modeAddress = 0;
- byte voltageAddress = 5;
- byte LVCModeAddress = 10;
- byte frequencyAddress = 15;
- byte frequencyMode;
- byte timeMultiplyer = 1;
- void setup() {
- delay(5);
- EEPROM.get(frequencyAddress, frequencyMode);
- if(frequencyMode != 1) {
- TCCR0B = TCCR0B & B11111000 | B00000100;
- timeMultiplyer = 4;
- }
- if(frequencyMode == 1){
- timeMultiplyer = 1;
- }
- // setup switch pin to use the internal pullup. Will read LOW when open
- pinMode(switchPin, INPUT);
- pinMode(LEDPin, OUTPUT);
- analogRead(voltPin);
- analogRead(voltPin);
- analogRead(voltPin);
- analogAverage1 = analogRead(voltPin);
- analogAverage2 = analogRead(voltPin);
- analogAverage3 = analogRead(voltPin);
- analogAverage4 = analogRead(voltPin);
- battAnalog = (analogAverage1 + analogAverage2 + analogAverage3 + analogAverage4) / 4;
- uBatt = ((battAnalog * 5.0) / 1023) * 5.5453;
- EEPROM.get(LVCModeAddress, LVCMode);
- if(LVCMode != 1) {
- LVCMode = 0;
- }
- if(uBatt < 9 && LVCMode == 0) {
- inputMode = 2;//2s mode LiOn
- uBattMin = 0.0;
- lBattMin = 5.5;
- lowBattVoltage = 6.3;
- }
- if(uBatt < 9 && LVCMode == 1) {
- inputMode = 2;//2s mode LiPo
- uBattMin = 0.0;
- lBattMin = 6.6;
- lowBattVoltage = 7.3;
- }
- if(uBatt > 9.5 && uBatt < 13.5 && LVCMode == 0) {
- inputMode = 3;//3s mode LiOn
- uBattMin = 0.0;
- lBattMin = 8.25;
- lowBattVoltage = 9.4;
- }
- if(uBatt > 9.5 && uBatt < 13.5 && LVCMode == 1) {
- inputMode = 3;//3s mode LiPo
- uBattMin = 0.0;
- lBattMin = 9.9;
- lowBattVoltage = 10.8;
- }
- if(uBatt > 13.5 && LVCMode == 1) {
- inputMode = 4;//4s Lipo
- uBattMin = 0.0;
- lBattMin = 13.2;
- lowBattVoltage = 14.8;
- }
- if(uBatt > 13.5 && LVCMode == 0) {
- inputMode = 4;//4s LiOn
- uBattMin = 0.0;
- lBattMin = 11.2;
- lowBattVoltage = 13.3;
- }
- //read output mode from EEPROM
- EEPROM.get(modeAddress, outputMode);
- if (outputMode < 0 || outputMode > 1) {
- outputMode = 0;
- }
- //read voltage setting from EEPROM
- EEPROM.get(voltageAddress, vRMS);
- }
- void loop() {
- unsigned long currentMillis = millis()*timeMultiplyer;
- if(currentMillis - sleepTimer > 15000) {
- enterSleep();
- }
- // read the switch state. Will read low when depressed
- switchPinState = digitalRead(switchPin);
- //read the battery voltage every loop
- analogAverage1 = analogRead(voltPin);
- analogAverage2 = analogRead(voltPin);
- analogAverage3 = analogRead(voltPin);
- analogAverage4 = analogRead(voltPin);
- battAnalog = (analogAverage1 + analogAverage2 + analogAverage3 + analogAverage4) / 4;
- uBatt = ((battAnalog * 5.0) / 1023) * 5.5453;
- if (uBatt < uBattMin) {
- deadBattFlag = 1;
- }
- if (uBatt >= lowBattVoltage) {
- lowBattFlag = 0;
- }
- //when the mod is locked
- if (switchPinState == HIGH && lockFlag == 1) {//fire switch when locked code with edge detection
- sleepTimer = currentMillis;
- if (lastSwitchState == LOW) {
- lastSwitchState = HIGH;
- holdTimer = currentMillis;
- switchClicks++;
- delay(100/timeMultiplyer);
- }
- }
- if(lastSwitchState == HIGH && currentMillis - holdTimer >= 3500 && outputMode == 0 && lockFlag == 1 && potValue > 15 && potValue < 495 && deadBattFlag == 0) { // when locked and in unregulated mode, save settings and turn on regulated mode.
- sleepTimer = currentMillis;
- blinkLED(3, 150, 150);
- holdTimer = currentMillis;
- outputMode = 1;
- pinMode(PWMPin, OUTPUT);
- digitalWrite(PWMPin, HIGH);
- delay(1/timeMultiplyer);
- //read the loaded battery voltage
- analogAverage1 = analogRead(voltPin);
- analogAverage2 = analogRead(voltPin);
- analogAverage3 = analogRead(voltPin);
- analogAverage4 = analogRead(voltPin);
- battAnalog = (analogAverage1 + analogAverage2 + analogAverage3 + analogAverage4) / 4;
- lBatt = ((battAnalog * 5.0) / 1023) * 5.5453;
- digitalWrite(PWMPin, LOW);
- // read the analog in value from the pot
- potValue = analogRead(potPin);
- if(potValue >= 511) potValue = 511;
- // map it to the range of the analog out:
- PWMOutputValue = map(potValue, 0, 511, 0, 255);
- // change the analog out value:
- dutyCycle = PWMOutputValue / 255;
- vRMS = lBatt * sqrt(dutyCycle);
- EEPROM.put(voltageAddress, vRMS);
- EEPROM.put(modeAddress, 1);
- }
- if(lastSwitchState == HIGH && currentMillis - holdTimer >= 3500 && outputMode == 1 && lockFlag == 1 && potValue > 15 && deadBattFlag == 0) {
- sleepTimer = currentMillis;
- blinkLED(1, 150, 150);
- holdTimer = currentMillis;
- outputMode = 0;
- EEPROM.put(modeAddress, 0);
- }
- if(lastSwitchState == HIGH && currentMillis - holdTimer >= 60000 && lockFlag == 1 && potValue <= 15 && LVCMode == 0 && deadBattFlag == 0) {
- sleepTimer = currentMillis;
- blinkLED(2, 500, 500);
- holdTimer = currentMillis;
- LVCMode = 1;
- EEPROM.put(LVCModeAddress, LVCMode);
- }
- if(lastSwitchState == HIGH && currentMillis - holdTimer >= 60000 && lockFlag == 1 && potValue <= 15 && LVCMode == 1 && deadBattFlag == 0) {
- sleepTimer = currentMillis;
- blinkLED(1, 500, 150);
- holdTimer = currentMillis;
- LVCMode = 0;
- EEPROM.put(LVCModeAddress, LVCMode);
- }
- if(lastSwitchState == HIGH && currentMillis - holdTimer >= 15000 && lockFlag == 1 && potValue >= 495 && deadBattFlag == 0) {
- sleepTimer = currentMillis;
- blinkLED(1, 150, 150);
- holdTimer = currentMillis;
- if(frequencyMode != 1) {
- EEPROM.put(frequencyAddress, 1);
- blinkLED(5, 150, 150);
- }
- if(frequencyMode == 1) {
- EEPROM.put(frequencyAddress, 0);
- blinkLED(2, 150, 150);
- }
- }
- // if the switch is depressed and mod isn't locked or hasn't fired yet, run this code then fire. This code will be skipped once it runs through once
- if(switchPinState == HIGH && lockFlag == 0 && fireFlag == 0 && readFlag == 0) {
- sleepTimer = currentMillis;
- delay(75/timeMultiplyer);
- switchClicks++;
- fireTimer = currentMillis;
- getReadings();
- }
- //if the mod is unlocked and when through the initial fire code, run this code
- if(switchPinState == HIGH && lockFlag == 0 && fireFlag == 1 && readFlag == 1) {
- sleepTimer = currentMillis;
- if (currentMillis - fireTimer > 10000) {
- fireTimer = 0;
- lockFlag = 1;
- blinkLED(4, 150, 150);
- modLocked();
- }
- else {
- fire();
- }
- }
- //Idle code goes here
- if(switchPinState == LOW ) {
- analogWrite(PWMPin, 0);
- digitalWrite(LEDPin, LOW);
- fireFlag = 0;
- readFlag = 0;
- lastSwitchState = LOW;
- potValue = analogRead(potPin);
- if (potValue >= 511) potValue = 511;
- }
- //if the fire switch is open, reset the click timer
- if (switchClicks == 0) {
- lockTimer = currentMillis;
- }
- //reset lock timer if a second has passed
- if (currentMillis - lockTimer > 1000) {
- switchClicks = 0;
- }
- //if the switch has been closed 4 times within 1 second, lock that shit.
- if (switchClicks == 3 && lockFlag == 0) {
- analogWrite(PWMPin, 0);
- blinkLED(4, 150, 150);
- modLocked();
- switchClicks = 0;
- }
- //if the switch has been closed 4 times within 1 second, unlock that shit.
- if (switchClicks == 3 && lockFlag == 1) {
- blinkLED(4, 150, 150);
- lockFlag = 0;
- switchClicks = 0;
- }
- }
- void getReadings() {
- unsigned long currentMillis = millis()*timeMultiplyer;
- pinMode(PWMPin, OUTPUT);
- digitalWrite(PWMPin, HIGH);
- delay(1/timeMultiplyer);
- //read the loaded battery voltage
- analogAverage1 = analogRead(voltPin);
- analogAverage2 = analogRead(voltPin);
- analogAverage3 = analogRead(voltPin);
- analogAverage4 = analogRead(voltPin);
- battAnalog = (analogAverage1 + analogAverage2 + analogAverage3 + analogAverage4) / 4;
- lBatt = ((battAnalog * 5.0) / 1023) * 5.5453;
- digitalWrite(PWMPin, LOW);
- if(lBatt < lBattMin || deadBattFlag == 1) {
- blinkLED(32767, 150, 150);
- }
- if(lBatt <= lowBattVoltage && lBatt >= lBattMin) {
- lowBattFlag = 1;
- }
- if(lBatt >= lBattMin && deadBattFlag == 0) {
- readFlag = 1;
- lowBattBlinkTimer = currentMillis;
- fire();
- }
- }
- void fire() {
- unsigned long currentMillis = millis()* timeMultiplyer;
- fireFlag = 1;
- //turn on LED indicator
- if(lowBattFlag == 0) {
- digitalWrite(LEDPin, HIGH);
- }
- if(lowBattFlag == 1 && currentMillis - lowBattBlinkTimer < lowBattBlinkTime) {
- digitalWrite(LEDPin, HIGH);
- }
- if(lowBattFlag == 1 && currentMillis - lowBattBlinkTimer >= lowBattBlinkTime && currentMillis - lowBattBlinkTimer < lowBattBlinkTime + 100) {
- digitalWrite(LEDPin, LOW);
- }
- if(lowBattFlag == 1 && currentMillis - lowBattBlinkTimer >= lowBattBlinkTime + 100 && currentMillis - lowBattBlinkTimer < lowBattBlinkTime + 200) {
- lowBattBlinkTimer = currentMillis;
- }
- if (outputMode == 0) {
- // read the analog in value from the pot
- potValue = analogRead(potPin);
- if(potValue >= 511) potValue = 511;
- // map it to the range of the analog out:
- PWMOutputValue = map(potValue, 0, 511, 0, 255);
- }
- if (outputMode == 1) {
- PWMOutputValue = (vRMS / lBatt * vRMS / lBatt) * 255;
- if (PWMOutputValue > 255) {
- PWMOutputValue = 255;
- }
- }
- analogWrite(PWMPin, PWMOutputValue);
- }
- void modLocked() {
- lockFlag = 1;
- analogWrite(PWMPin, 0);
- digitalWrite(LEDPin, LOW);
- fireFlag = 0;
- }
- void blinkLED(int blinks, int LEDOn, int LEDOff) {
- for (int i=1; i <= blinks; i++){
- digitalWrite(LEDPin, HIGH);
- delay(LEDOn/timeMultiplyer);
- digitalWrite(LEDPin, LOW);
- delay(LEDOff/timeMultiplyer);
- }
- }
- // Empty interrupt handler for INT0
- EMPTY_INTERRUPT(PCINT0_vect);
- void enterSleep(){
- digitalWrite(LEDPin, LOW); // switch LED off
- analogWrite(PWMPin, 0); // stop firing (unecessary, but…)
- cli(); // disable interrupts
- GIMSK |= 1<<PCIE; // enable PCINTs
- PCMSK |= 1<<PCINT2; // enable PCINT2
- sleep_bod_disable();
- set_sleep_mode(SLEEP_MODE_PWR_DOWN);
- sleep_enable();
- sei(); // re-enable interrupts
- sleep_cpu(); // power down...
- cli(); // disable interrupts
- sleep_disable();
- GIMSK &= ~(1<<PCIE); // disable INT0
- sei(); // re-enable interrupts
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement