Hello.
I wrote the code here, it generally works, but sometimes it hangs for some reason.
Here is the code itself:
#include <EEPROMex.h> //Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° Π΄Π»Ρ ΡΠ°Π±ΠΎΡΡ ΡΠΎ Π²Π½ΡΡΡΠ΅Π½Π½Π΅ΠΉ ΠΏΠ°ΠΌΡΡΡΡ Π°ΡΠ΄ΡΠΈΠ½ΠΎ #include <avr/sleep.h> //Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° ΡΠ΅ΠΆΠΈΠΌΠΎΠ² ΡΠ½Π° #define mosfet_pin 2 //ΡΠ΅Π»Π΅ ΠΈΠ»ΠΈ ΠΌΠΎΡΡΠ΅Ρ Π½Π° D2 #define trigger_pin 3 //ΡΠΏΡΡΠΊΠΎΠ²Π°Ρ ΠΊΠ½ΠΎΠΏΠΊΠ° Π½Π° D3 #define out_pin 4 //5v D4 #define out_pin2 5 //5v D5 #define fireled 6 //ΠΏΠΈΠ½ ΠΈΠ½Π΄ΠΈΠΊΠ°ΡΠΎΡΠ° ΡΠ°Π±ΠΎΡΡ ΠΈ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠΈ volatile unsigned long lastshot; //Π²ΡΠ΅ΠΌΡ ΠΏΠΎΡΠ»Π΅Π΄Π½Π΅Π³ΠΎ Π½Π°ΠΆΠ°ΡΠΈΡ Π΄Π»Ρ ΡΠ°ΠΉΠΌΠ΅ΡΠ° ΡΠ½Π° boolean trig_state; //ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½Π°Ρ Π΄Π»Ρ Ρ
ΡΠ°Π½Π΅Π½ΠΈΡ ΡΠ΅ΠΊΡΡΠ΅Π³ΠΎ ΡΠΎΡΡΠΎΡΠ½ΡΠΈ ΠΊΠ½ΠΎΠΏΠΊΠΈ boolean flag; //ΡΠ»Π°ΠΆΠΎΠΊ Π΄Π»Ρ Π·Π°ΠΏΠΎΠΌΠΈΠ½Π°Π½ΠΈΡ ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΠΊΠ½ΠΎΠΏΠΊΠΈ boolean block; //ΡΠ»Π°ΠΆΠΎΠΊ Π΄Π»Ρ Π·Π°ΠΏΠΎΠΌΠΈΠ½Π°Π½ΠΈΡ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠΈ boolean waitblink; //ΡΠ»Π°ΠΆΠΎΠΊ Π΄Π»Ρ ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΡ 5 ΠΌΠΈΠ³Π°Π½ΠΈΠΉ int presscount; //ΡΡΠΈΡΠ°Π΅ΠΌ ΠΊΠΎΠ»-Π²ΠΎ Π½Π°ΠΆΠ°ΡΠΈΠΉ byte trigger; //ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΡΠΏΡΡΠΊΠΎΠ²ΠΎΠΉ ΠΊΠ½ΠΎΠΏΠΊΠΈ float my_vcc_const; // ΠΊΠΎΠ½ΡΡΠ°Π½ΡΠ° Π²ΠΎΠ»ΡΡΠΌΠ΅ΡΡΠ° int voltage; void setup() { Serial.begin(9600); my_vcc_const = EEPROM.readFloat(8); block = 0; pinMode(mosfet_pin, OUTPUT); //ΡΡΠΎΡΠΌΠΈΡΠΎΠ²Π°ΡΡ ΠΏΠΈΠ½ ΡΠ΅Π»Π΅ ΠΊΠ°ΠΊ Π²ΡΡ
ΠΎΠ΄ pinMode(trigger_pin, INPUT_PULLUP); //ΠΏΠΈΠ½ ΠΊΠ½ΠΎΠΏΠΊΠΈ ΠΏΠΎΠ΄ΡΡΠ½ΡΡ Π²Π½ΡΡΡΠ΅Π½Π½ΠΈΠΌ ΡΠ΅Π·ΠΈΡΡΠΎΡΠΎΠΌ, ΡΠ΅Π·ΠΈΡΡΠΎΡ Π½Π° 10 ΠΊΠΠΌ ΠΠ ΠΠ£ΠΠΠ pinMode(out_pin, OUTPUT); //5v pinMode(out_pin2, OUTPUT); //5v attachInterrupt(1, trigger_press, FALLING); //Π°ΠΏΠΏΠ°ΡΠ°ΡΠ½ΠΎΠ΅ ΠΏΡΠ΅ΡΡΠ²Π°Π½ΠΈΠ΅ ΠΏΡΠΈ Π½Π°ΠΆΠ°ΡΠΈΠΈ Π½Π° ΠΊΠ½ΠΎΠΏΠΊΡ (ΠΏΡΠΎΡΠ½ΡΡΡΡΡ) } void trigger_press() { //ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊ ΠΏΡΠ΅ΡΡΠ²Π°Π½ΠΈΡ //ΠΏΡΠΎΡΡΠΏΠ°Π΅ΠΌΡΡ ΠΏΡΠΈ Π½Π°ΠΆΠ°ΡΠΈΠΈ ΠΊΠ½ΠΎΠΏΠΊΠΈ! } void loop() { voltage = readVcc(); //Serial.println(voltage); trig_state = digitalRead(trigger_pin); //ΡΡΠΈΡΠ°ΡΡ ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΊΠ½ΠΎΠΏΠΊΠΈ fire if(trig_state == 1 && flag == 1) //Π΅ΡΠ»ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ° ΠΎΡΠΆΠ°ΡΠ° ΠΈ ΡΠ»Π°Π³=1 { digitalWrite(LED_BUILTIN, LOW); digitalWrite(mosfet_pin, LOW); //Π·Π°ΠΊΡΡΡΡ ΠΌΠΎΡΡΠ΅Ρ flag=0; //ΡΡΠ°Π²ΠΈΠΌ ΡΠ»Π°ΠΆΠΎΠΊ, ΡΡΠΎ ΠΊΠ½ΠΎΠΏΠΊΠ° Π±ΠΎΠ»ΡΡΠ΅ Π½Π΅ Π½Π°ΠΆΠ°ΡΠ° Serial.print("STOP FIRE!!!"); } if(trig_state == 0 && flag == 0 && waitblink == 0) //Π΅ΡΠ»ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ° fire Π½Π°ΠΆΠ°ΡΠ° ΡΠ»Π°Π³=0 ΠΈ ΠΌΠΎΠ΄ Π½Π΅ ΠΌΠΈΠ³Π°Π΅Ρ { if(presscount > 3) { if(block == 0) { waitblink = 1; for(int i=0; i<5; i++) { digitalWrite(LED_BUILTIN, HIGH); delay(200); digitalWrite(LED_BUILTIN, LOW); delay(200); } waitblink = 0; block = 1; Serial.print("BOXMOD IS BLOCKED!!!"); } else { //delay(200); waitblink = 1; for(int i=0; i<5; i++) { digitalWrite(LED_BUILTIN, HIGH); delay(200); digitalWrite(LED_BUILTIN, LOW); delay(200); } waitblink = 0; block = 0; Serial.print("BOXMOD UNLOCKED!!!"); } } if(block == 0) { digitalWrite(LED_BUILTIN, HIGH); digitalWrite(mosfet_pin, HIGH); //ΠΎΡΠΊΡΡΡΡ ΠΌΠΎΡΡΠ΅Ρ Serial.print("FIRE!!!"); Serial.print("Press count: "); Serial.println(presscount, 3); Serial.print("Wait blink: "); Serial.println(waitblink, 3); } presscount ++; lastshot=millis(); //Π·Π°ΠΏΠΎΠΌΠ½ΠΈΡΡ Π²ΡΠ΅ΠΌΡ ΠΏΠΎΡΠ»Π΅Π΄Π½Π΅Π³ΠΎ Π½Π°ΠΆΠ°ΡΠΈΡ (Π΄Π»Ρ ΡΠ°ΠΉΠΌΠ΅ΡΠ° ΡΠ½Π°) flag=1; //ΠΏΠΎΡΡΠ°Π²ΠΈΡΡ ΡΠ»Π°ΠΆΠΎΠΊ, ΡΡΠΎ ΠΊΠ½ΠΎΠΏΠΊΠ° Π½Π°ΠΆΠ°ΡΠ° } // ΡΡΠΎΡ ΠΊΡΡΠΎΠΊ Π΄Π°ΡΡ ΠΊΠΎΠΌΠ°Π½Π΄Ρ ΡΠΏΠ°ΡΡ if (millis()-lastshot > 300) //Π΅ΡΠ»ΠΈ ΠΏΠΎΡΠ»Π΅ ΠΏΠΎΡΠ»Π΅Π΄Π½Π΅Π³ΠΎ Π½Π°ΠΆΠ°ΡΠΈΡ ΠΏΡΠΎΡΠ»ΠΎ Π±ΠΎΠ»ΡΡΠ΅ 3 ΡΠ΅ΠΊΡΠ½Π΄ { set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Π²ΡΠ±ΠΎΡ ΡΠ΅ΠΆΠΈΠΌΠ° ΡΠ½Π΅ΡΠ³ΠΎΠΏΠΎΡΡΠ΅Π±Π»Π΅Π½ΠΈΡ sleep_mode(); // ΡΡ
ΠΎΠ΄ΠΈΠΌ Π² ΡΠΏΡΡΠΊΡ presscount = 0; } // ΡΡΠΎΡ ΠΊΡΡΠΎΠΊ Π΄Π°ΡΡ ΠΊΠΎΠΌΠ°Π½Π΄Ρ ΡΠΏΠ°ΡΡ delay(1); //Π·Π°Π΄Π΅ΡΠΆΠΊΠ° Π΄Π»Ρ ΡΡΠ°Π±ΠΈΠ»ΡΠ½ΠΎΡΡΠΈ ΡΠ°Π±ΠΎΡΡ ΠΏΡΠΎΡΠΈΠ²ΠΊΠΈ } void calibration() { //--------ΠΊΠ°Π»ΠΈΠ±ΡΠΎΠ²ΠΊΠ°---------- for (byte i = 0; i < 7; i++) EEPROM.writeInt(i, 0); // ΡΠΈΡΡΠΈΠΌ EEPROM Π΄Π»Ρ ΡΠ²ΠΎΠΈΡ
Π½ΡΠΆΠ΄ my_vcc_const = 1.1; Serial.print("Real VCC is: "); Serial.println(readVcc()); // ΠΎΠ±ΡΠ°Π΅ΠΌΡΡ Ρ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Π΅ΠΌ Serial.println("Write your VCC (in millivolts)"); while (Serial.available() == 0); int Vcc = Serial.parseInt(); // Π½Π°ΠΏΡΡΠΆΠ΅Π½ΠΈΠ΅ ΠΎΡ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ float real_const = (float)1.1 * Vcc / readVcc(); // ΡΠ°ΡΡΡΡ ΠΊΠΎΠ½ΡΡΠ°Π½ΡΡ Serial.print("New voltage constant: "); Serial.println(real_const, 3); EEPROM.writeFloat(8, real_const); // Π·Π°ΠΏΠΈΡΡ Π² EEPROM while (1); // ΡΠΉΡΠΈ Π² Π±Π΅ΡΠΊΠΎΠ½Π΅ΡΠ½ΡΠΉ ΡΠΈΠΊΠ» //------ΠΊΠΎΠ½Π΅Ρ ΠΊΠ°Π»ΠΈΠ±ΡΠΎΠ²ΠΊΠΈ------- } long readVcc() { //ΡΡΠ½ΠΊΡΠΈΡ ΡΡΠ΅Π½ΠΈΡ Π²Π½ΡΡΡΠ΅Π½Π½Π΅Π³ΠΎ ΠΎΠΏΠΎΡΠ½ΠΎΠ³ΠΎ Π½Π°ΠΏΡΡΠΆΠ΅Π½ΠΈΡ, ΡΠ½ΠΈΠ²Π΅ΡΡΠ°Π»ΡΠ½Π°Ρ (Π΄Π»Ρ Π²ΡΠ΅Ρ
Π°ΡΠ΄ΡΠΈΠ½) #if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); #elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) ADMUX = _BV(MUX5) | _BV(MUX0); #elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) ADMUX = _BV(MUX3) | _BV(MUX2); #else ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); #endif delay(2); // Wait for Vref to settle ADCSRA |= _BV(ADSC); // Start conversion while (bit_is_set(ADCSRA, ADSC)); // measuring uint8_t low = ADCL; // must read ADCL first - it then locks ADCH uint8_t high = ADCH; // unlocks both long result = (high << 8) | low; result = my_vcc_const * 1023 * 1000 / result; // ΡΠ°ΡΡΡΡ ΡΠ΅Π°Π»ΡΠ½ΠΎΠ³ΠΎ VCC return result; // Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ VCC } Video for clarity: https://vk.com/video16479439_456239166