Залипание
- Войдите на сайт для отправки комментариев
Втр, 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, он знает наверное в чем причина, ведь это он писал код))))
я запретил.
От его кода там почти ничего не осталось, в этом и проблема...