Залипание
- Войдите на сайт для отправки комментариев
Втр, 28/02/2017 - 16:05
Всем привет. Написал тут код, он в целом работает, но иногда зависает по какойто причине. Вот сам код:
/* Created 2016 by AlexGyver AlexGyver Home Labs Inc. */ #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 }
Вот видео для наглядности: https://vk.com/video16479439_456239166
Ошибка доступа.
Блин, ну короче дело в том, что при нажатии на кнопку срабатывает реле, при отпускании выключается, но бывает что оно остается включенным и выключается только при повторном нажатии на кнопку. Вот.
Спросите у AlexGyver, он знает наверное в чем причина, ведь это он писал код))))
я запретил.
От его кода там почти ничего не осталось, в этом и проблема...