Advertisement
Guest User

Untitled

a guest
Jan 23rd, 2020
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.95 KB | None | 0 0
  1. #include <EEPROM.h>
  2. #include <avr/sleep.h>
  3. #include <avr/power.h>
  4.  
  5. int PWMPin = 0;
  6. int potPin = A3;
  7. int potValue;
  8. int switchPin = 2;
  9. int LEDPin = 1;
  10. int voltPin = A2;
  11.  
  12. int switchPinState;
  13. int lastSwitchState = LOW;
  14. float PWMOutputValue = 0;
  15. float uBatt;//unloaded battery voltage
  16. int battAnalog;
  17. int analogAverage1;
  18. int analogAverage2;
  19. int analogAverage3;
  20. int analogAverage4;
  21. float lBatt;//loaded battery voltage
  22. int inputMode;//2 for 2s, 3 for 3s, 4 for 4s
  23. float uBattMin;
  24. float lBattMin;
  25. float lowBattVoltage;
  26. int outputMode; // 0 for unregulated 1 for regulated
  27. int LVCMode; // 0 for LiOn 1 for LiPo
  28. int deadBattFlag; // flag for low(dead) unloaded voltage
  29. int lowBattFlag; // flag for low battery
  30. long lowBattBlinkTimer; //timer for low batt blink
  31. int lowBattBlinkTime = 1000;
  32. int lowBattBlinkState = LOW;
  33.  
  34. unsigned long sleepTimer = 0;
  35.  
  36.  
  37.  
  38. float vRMS;
  39. float dutyCycle;
  40.  
  41. long lockTimer = 0;
  42. long fireTimer = 0;
  43. long holdTimer = 0;
  44. byte fireFlag = 0;
  45. byte lockFlag = 0;
  46. byte readFlag = 0;
  47. byte switchClicks = 0;
  48.  
  49. byte modeAddress = 0;
  50. byte voltageAddress = 5;
  51. byte LVCModeAddress = 10;
  52. byte frequencyAddress = 15;
  53. byte frequencyMode;
  54. byte timeMultiplyer = 1;
  55.  
  56.  
  57.  
  58.  
  59.  
  60. void setup() {
  61. delay(5);
  62. EEPROM.get(frequencyAddress, frequencyMode);
  63.  
  64. if(frequencyMode != 1) {
  65. TCCR0B = TCCR0B & B11111000 | B00000100;
  66. timeMultiplyer = 4;
  67. }
  68. if(frequencyMode == 1){
  69. timeMultiplyer = 1;
  70. }
  71. // setup switch pin to use the internal pullup. Will read LOW when open
  72. pinMode(switchPin, INPUT);
  73. pinMode(LEDPin, OUTPUT);
  74. analogRead(voltPin);
  75. analogRead(voltPin);
  76. analogRead(voltPin);
  77. analogAverage1 = analogRead(voltPin);
  78. analogAverage2 = analogRead(voltPin);
  79. analogAverage3 = analogRead(voltPin);
  80. analogAverage4 = analogRead(voltPin);
  81. battAnalog = (analogAverage1 + analogAverage2 + analogAverage3 + analogAverage4) / 4;
  82. uBatt = ((battAnalog * 5.0) / 1023) * 5.5453;
  83. EEPROM.get(LVCModeAddress, LVCMode);
  84. if(LVCMode != 1) {
  85. LVCMode = 0;
  86. }
  87.  
  88. if(uBatt < 9 && LVCMode == 0) {
  89. inputMode = 2;//2s mode LiOn
  90. uBattMin = 0.0;
  91. lBattMin = 5.5;
  92. lowBattVoltage = 6.3;
  93.  
  94. }
  95.  
  96. if(uBatt < 9 && LVCMode == 1) {
  97. inputMode = 2;//2s mode LiPo
  98. uBattMin = 0.0;
  99. lBattMin = 6.6;
  100. lowBattVoltage = 7.3;
  101. }
  102. if(uBatt > 9.5 && uBatt < 13.5 && LVCMode == 0) {
  103. inputMode = 3;//3s mode LiOn
  104. uBattMin = 0.0;
  105. lBattMin = 8.25;
  106. lowBattVoltage = 9.4;
  107. }
  108.  
  109.  
  110. if(uBatt > 9.5 && uBatt < 13.5 && LVCMode == 1) {
  111. inputMode = 3;//3s mode LiPo
  112. uBattMin = 0.0;
  113. lBattMin = 9.9;
  114. lowBattVoltage = 10.8;
  115. }
  116. if(uBatt > 13.5 && LVCMode == 1) {
  117. inputMode = 4;//4s Lipo
  118. uBattMin = 0.0;
  119. lBattMin = 13.2;
  120. lowBattVoltage = 14.8;
  121. }
  122. if(uBatt > 13.5 && LVCMode == 0) {
  123. inputMode = 4;//4s LiOn
  124. uBattMin = 0.0;
  125. lBattMin = 11.2;
  126. lowBattVoltage = 13.3;
  127. }
  128.  
  129. //read output mode from EEPROM
  130. EEPROM.get(modeAddress, outputMode);
  131. if (outputMode < 0 || outputMode > 1) {
  132. outputMode = 0;
  133. }
  134. //read voltage setting from EEPROM
  135. EEPROM.get(voltageAddress, vRMS);
  136. }
  137.  
  138. void loop() {
  139. unsigned long currentMillis = millis()*timeMultiplyer;
  140.  
  141. if(currentMillis - sleepTimer > 15000) {
  142. enterSleep();
  143. }
  144. // read the switch state. Will read low when depressed
  145. switchPinState = digitalRead(switchPin);
  146.  
  147. //read the battery voltage every loop
  148. analogAverage1 = analogRead(voltPin);
  149. analogAverage2 = analogRead(voltPin);
  150. analogAverage3 = analogRead(voltPin);
  151. analogAverage4 = analogRead(voltPin);
  152. battAnalog = (analogAverage1 + analogAverage2 + analogAverage3 + analogAverage4) / 4;
  153. uBatt = ((battAnalog * 5.0) / 1023) * 5.5453;
  154.  
  155.  
  156. if (uBatt < uBattMin) {
  157. deadBattFlag = 1;
  158. }
  159.  
  160. if (uBatt >= lowBattVoltage) {
  161. lowBattFlag = 0;
  162. }
  163.  
  164. //when the mod is locked
  165. if (switchPinState == HIGH && lockFlag == 1) {//fire switch when locked code with edge detection
  166. sleepTimer = currentMillis;
  167. if (lastSwitchState == LOW) {
  168.  
  169. lastSwitchState = HIGH;
  170.  
  171. holdTimer = currentMillis;
  172. switchClicks++;
  173. delay(100/timeMultiplyer);
  174. }
  175. }
  176. 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.
  177. sleepTimer = currentMillis;
  178. blinkLED(3, 150, 150);
  179. holdTimer = currentMillis;
  180. outputMode = 1;
  181. pinMode(PWMPin, OUTPUT);
  182. digitalWrite(PWMPin, HIGH);
  183. delay(1/timeMultiplyer);
  184. //read the loaded battery voltage
  185. analogAverage1 = analogRead(voltPin);
  186. analogAverage2 = analogRead(voltPin);
  187. analogAverage3 = analogRead(voltPin);
  188. analogAverage4 = analogRead(voltPin);
  189. battAnalog = (analogAverage1 + analogAverage2 + analogAverage3 + analogAverage4) / 4;
  190. lBatt = ((battAnalog * 5.0) / 1023) * 5.5453;
  191. digitalWrite(PWMPin, LOW);
  192. // read the analog in value from the pot
  193. potValue = analogRead(potPin);
  194. if(potValue >= 511) potValue = 511;
  195. // map it to the range of the analog out:
  196. PWMOutputValue = map(potValue, 0, 511, 0, 255);
  197. // change the analog out value:
  198. dutyCycle = PWMOutputValue / 255;
  199. vRMS = lBatt * sqrt(dutyCycle);
  200. EEPROM.put(voltageAddress, vRMS);
  201. EEPROM.put(modeAddress, 1);
  202. }
  203. if(lastSwitchState == HIGH && currentMillis - holdTimer >= 3500 && outputMode == 1 && lockFlag == 1 && potValue > 15 && deadBattFlag == 0) {
  204. sleepTimer = currentMillis;
  205. blinkLED(1, 150, 150);
  206. holdTimer = currentMillis;
  207. outputMode = 0;
  208. EEPROM.put(modeAddress, 0);
  209.  
  210.  
  211. }
  212. if(lastSwitchState == HIGH && currentMillis - holdTimer >= 60000 && lockFlag == 1 && potValue <= 15 && LVCMode == 0 && deadBattFlag == 0) {
  213. sleepTimer = currentMillis;
  214. blinkLED(2, 500, 500);
  215. holdTimer = currentMillis;
  216. LVCMode = 1;
  217.  
  218. EEPROM.put(LVCModeAddress, LVCMode);
  219. }
  220.  
  221. if(lastSwitchState == HIGH && currentMillis - holdTimer >= 60000 && lockFlag == 1 && potValue <= 15 && LVCMode == 1 && deadBattFlag == 0) {
  222. sleepTimer = currentMillis;
  223. blinkLED(1, 500, 150);
  224. holdTimer = currentMillis;
  225. LVCMode = 0;
  226. EEPROM.put(LVCModeAddress, LVCMode);
  227. }
  228.  
  229. if(lastSwitchState == HIGH && currentMillis - holdTimer >= 15000 && lockFlag == 1 && potValue >= 495 && deadBattFlag == 0) {
  230. sleepTimer = currentMillis;
  231. blinkLED(1, 150, 150);
  232. holdTimer = currentMillis;
  233. if(frequencyMode != 1) {
  234. EEPROM.put(frequencyAddress, 1);
  235. blinkLED(5, 150, 150);
  236. }
  237. if(frequencyMode == 1) {
  238. EEPROM.put(frequencyAddress, 0);
  239. blinkLED(2, 150, 150);
  240. }
  241. }
  242. // 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
  243. if(switchPinState == HIGH && lockFlag == 0 && fireFlag == 0 && readFlag == 0) {
  244. sleepTimer = currentMillis;
  245. delay(75/timeMultiplyer);
  246. switchClicks++;
  247. fireTimer = currentMillis;
  248. getReadings();
  249. }
  250.  
  251. //if the mod is unlocked and when through the initial fire code, run this code
  252. if(switchPinState == HIGH && lockFlag == 0 && fireFlag == 1 && readFlag == 1) {
  253. sleepTimer = currentMillis;
  254. if (currentMillis - fireTimer > 10000) {
  255. fireTimer = 0;
  256. lockFlag = 1;
  257. blinkLED(4, 150, 150);
  258. modLocked();
  259. }
  260. else {
  261. fire();
  262. }
  263. }
  264. //Idle code goes here
  265. if(switchPinState == LOW ) {
  266. analogWrite(PWMPin, 0);
  267. digitalWrite(LEDPin, LOW);
  268. fireFlag = 0;
  269. readFlag = 0;
  270. lastSwitchState = LOW;
  271.  
  272. potValue = analogRead(potPin);
  273. if (potValue >= 511) potValue = 511;
  274.  
  275. }
  276. //if the fire switch is open, reset the click timer
  277. if (switchClicks == 0) {
  278. lockTimer = currentMillis;
  279. }
  280. //reset lock timer if a second has passed
  281. if (currentMillis - lockTimer > 1000) {
  282. switchClicks = 0;
  283. }
  284. //if the switch has been closed 4 times within 1 second, lock that shit.
  285. if (switchClicks == 3 && lockFlag == 0) {
  286. analogWrite(PWMPin, 0);
  287. blinkLED(4, 150, 150);
  288. modLocked();
  289. switchClicks = 0;
  290. }
  291. //if the switch has been closed 4 times within 1 second, unlock that shit.
  292. if (switchClicks == 3 && lockFlag == 1) {
  293. blinkLED(4, 150, 150);
  294. lockFlag = 0;
  295. switchClicks = 0;
  296. }
  297. }
  298.  
  299. void getReadings() {
  300. unsigned long currentMillis = millis()*timeMultiplyer;
  301. pinMode(PWMPin, OUTPUT);
  302. digitalWrite(PWMPin, HIGH);
  303. delay(1/timeMultiplyer);
  304. //read the loaded battery voltage
  305. analogAverage1 = analogRead(voltPin);
  306. analogAverage2 = analogRead(voltPin);
  307. analogAverage3 = analogRead(voltPin);
  308. analogAverage4 = analogRead(voltPin);
  309. battAnalog = (analogAverage1 + analogAverage2 + analogAverage3 + analogAverage4) / 4;
  310. lBatt = ((battAnalog * 5.0) / 1023) * 5.5453;
  311. digitalWrite(PWMPin, LOW);
  312. if(lBatt < lBattMin || deadBattFlag == 1) {
  313. blinkLED(32767, 150, 150);
  314. }
  315. if(lBatt <= lowBattVoltage && lBatt >= lBattMin) {
  316. lowBattFlag = 1;
  317. }
  318. if(lBatt >= lBattMin && deadBattFlag == 0) {
  319. readFlag = 1;
  320. lowBattBlinkTimer = currentMillis;
  321. fire();
  322. }
  323. }
  324.  
  325.  
  326. void fire() {
  327. unsigned long currentMillis = millis()* timeMultiplyer;
  328. fireFlag = 1;
  329. //turn on LED indicator
  330. if(lowBattFlag == 0) {
  331. digitalWrite(LEDPin, HIGH);
  332. }
  333. if(lowBattFlag == 1 && currentMillis - lowBattBlinkTimer < lowBattBlinkTime) {
  334. digitalWrite(LEDPin, HIGH);
  335. }
  336. if(lowBattFlag == 1 && currentMillis - lowBattBlinkTimer >= lowBattBlinkTime && currentMillis - lowBattBlinkTimer < lowBattBlinkTime + 100) {
  337. digitalWrite(LEDPin, LOW);
  338. }
  339. if(lowBattFlag == 1 && currentMillis - lowBattBlinkTimer >= lowBattBlinkTime + 100 && currentMillis - lowBattBlinkTimer < lowBattBlinkTime + 200) {
  340. lowBattBlinkTimer = currentMillis;
  341. }
  342. if (outputMode == 0) {
  343. // read the analog in value from the pot
  344. potValue = analogRead(potPin);
  345. if(potValue >= 511) potValue = 511;
  346. // map it to the range of the analog out:
  347. PWMOutputValue = map(potValue, 0, 511, 0, 255);
  348. }
  349. if (outputMode == 1) {
  350. PWMOutputValue = (vRMS / lBatt * vRMS / lBatt) * 255;
  351. if (PWMOutputValue > 255) {
  352. PWMOutputValue = 255;
  353. }
  354. }
  355. analogWrite(PWMPin, PWMOutputValue);
  356. }
  357.  
  358. void modLocked() {
  359. lockFlag = 1;
  360. analogWrite(PWMPin, 0);
  361. digitalWrite(LEDPin, LOW);
  362. fireFlag = 0;
  363. }
  364.  
  365. void blinkLED(int blinks, int LEDOn, int LEDOff) {
  366. for (int i=1; i <= blinks; i++){
  367. digitalWrite(LEDPin, HIGH);
  368. delay(LEDOn/timeMultiplyer);
  369. digitalWrite(LEDPin, LOW);
  370. delay(LEDOff/timeMultiplyer);
  371. }
  372.  
  373. }
  374.  
  375. // Empty interrupt handler for INT0
  376. EMPTY_INTERRUPT(PCINT0_vect);
  377. void enterSleep(){
  378. digitalWrite(LEDPin, LOW); // switch LED off
  379. analogWrite(PWMPin, 0); // stop firing (unecessary, but…)
  380. cli(); // disable interrupts
  381. GIMSK |= 1<<PCIE; // enable PCINTs
  382. PCMSK |= 1<<PCINT2; // enable PCINT2
  383. sleep_bod_disable();
  384. set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  385. sleep_enable();
  386. sei(); // re-enable interrupts
  387. sleep_cpu(); // power down...
  388. cli(); // disable interrupts
  389. sleep_disable();
  390. GIMSK &= ~(1<<PCIE); // disable INT0
  391. sei(); // re-enable interrupts
  392.  
  393. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement