Ошибка после срабатывания сенсорной кнопки
- Войдите на сайт для отправки комментариев
Всем добрый день! Сново обращаюсь к вам за помощью. Делаю небольшое устройство для регулировки мощности мини-паяльника. Суть простая: две кнопки + и - для ШИМа паяльника. 3 светодиода с Шим для индикации работы. Таймер для отключения паяльника если долго бездействует. И сенсорная кнопка - взяли паяльник в руки - таймер сбрасывается и паяльник работает. Все вроде работает. ШИМы регулируются как надо. Таймер работает (правда сбились настройки для delay() но это ерунда). Сенсорная кнопка тоже работет. НО! Стоит хотя бы раз дотронуться до сенсорной кнопки и таймер уже не срабатывает. То есть если включить устройство и не трогать, то через некоторое время сработает таймер и отключит устройство. Если посте этого дотронутся до сенсора то паяльник включается и больше не выключается. Можете взлянуть и сказать что не так? Скетч прилагаю:
#include <EEPROM.h> #include <CapSense.h>; volatile int payalnik = 3; // основной пин - выход с шимом volatile int ledR = 12; // выход ШИМ на зеленый и синий светодиоды volatile int ledG = 13; // выход ШИМ на красный светодиод volatile int ledRgnd = 17; // "земли" на светодиоды volatile int ledGgnd = 8; volatile int ledBgnd = 16; volatile int butcount = 0; // пременная для "антидребезга" кнопок volatile int PWMledG; // ШИМ для светодиодов volatile int PWMledR; volatile int PWMledB = 0; volatile int PWMpayalnik = EEPROM.read(0); // ШИМ для основного пина volatile int i=1; //просто чсетчики volatile int son=0; volatile byte mode = 0; // режим работы программы long temp1; //переменная для чтения сенсорной кнопки CapSense Sensor1 = CapSense(14,15); // настройка сенсорной кнопки void setup() { pinMode(payalnik, OUTPUT); pinMode(ledR, OUTPUT); pinMode(ledG, OUTPUT); pinMode(ledRgnd, OUTPUT); pinMode(ledGgnd, OUTPUT); pinMode(ledBgnd, OUTPUT); digitalWrite(ledRgnd, LOW); digitalWrite(ledGgnd, LOW); digitalWrite(ledBgnd, HIGH); ASSR = 0x00; //настройка таймеров TCCR0|=(1<<COM01)|(1<<WGM00); TCCR2 = 0b00000111; TIMSK|=(1<<TOIE2); sei(); pinMode(4, INPUT); // кнопки pinMode(7, INPUT); PORTB |=(1<<PB4)|(1<<PB7); LED_rejim(); // режим для светодиодов analogWrite(payalnik, ~PWMpayalnik); // ШИМ } void loop() { temp1 = Sensor1.capSense(30); // считываем значение с сенсорной кнопки (было касание / нет) if (temp1 > 80) // если было касание { //TCNT2 = 0; mode = 0; // изменяем режим на активный son = 0; // сбрасываем счетчик "засыпания" PWMledB = 0; // отключаем синий светодиод i=1; // сбрасываем счетчик digitalWrite(ledRgnd, LOW); // устанавливаем режим работы digitalWrite(ledGgnd, LOW); digitalWrite(ledBgnd, HIGH); analogWrite(payalnik, ~PWMpayalnik); analogWrite(ledR, PWMledR); analogWrite(ledG, PWMledG); } switch (mode) { case 0: be_work(); // основной режим работы break; case 1: analogWrite(payalnik, ~0); // переходим в режим ожидания отключаем все analogWrite(ledR, 0); analogWrite(ledG, 0); digitalWrite(ledRgnd, HIGH); digitalWrite(ledGgnd, HIGH); digitalWrite(ledBgnd, LOW); mode = 2; case 2: be_sleep(); // режим ожидания break; } delay(50); } //--------------------------------- прерывание по переполнению таймера ISR(TIMER2_OVF_vect) { if (son < 3600){//27500 //настройка на 2 минуты - после включается режим ожидания son = son + 1; } else { mode = 1; // переключение в режим ожидания } } //-----------------------------------ШИМим синим светодиодом в режиме ожидания void be_sleep() // режим сна. мигаем синим светодиодом { PWMledB = PWMledB + i; analogWrite(ledG, PWMledB); if (PWMledB >= 255) {i=i*-1;} if (PWMledB <= 0) {i=i*-1;} delay (80); } //------------------------------------Режимы свечения светодиодов красного и зеленого void LED_rejim() { if (PWMpayalnik > 245){ PWMledR = 255; PWMledG = 0; } else if (PWMpayalnik > 235){ PWMledR = 255; PWMledG = 101; } else if (PWMpayalnik > 225){ PWMledR = 255; PWMledG = 204; } else if (PWMpayalnik > 215){ PWMledR = 255; PWMledG = 255; } else if (PWMpayalnik > 205){ PWMledR = 204; PWMledG = 255; } else if (PWMpayalnik > 195){ PWMledR = 101; PWMledG = 255; } else if (PWMpayalnik < 196){ PWMledR = 0; PWMledG = 255; } analogWrite(ledR, PWMledR); analogWrite(ledG, PWMledG); } //-------------------------------------// основной режим работы. реакция на кнопки. void be_work() { if (!(PINB & (1<<PINB7))) // если кнопка нажата { if (butcount < 6) // отсеиваем дребезг { butcount++; } else { PWMpayalnik = PWMpayalnik + 10; // повышаем ШИМ if (PWMpayalnik > 255) { PWMpayalnik=255; } EEPROM.write(0, PWMpayalnik); LED_rejim(); analogWrite(payalnik, ~PWMpayalnik); delay (4000); } } else if (!(PINB & (1<<PINB4))) { if (butcount < 6) { butcount++; } else { if (PWMpayalnik > 20) { PWMpayalnik = PWMpayalnik - 10; EEPROM.write(0, PWMpayalnik); LED_rejim(); analogWrite(payalnik, ~PWMpayalnik); delay (4000); } } } else { if (butcount > 0) { butcount--; } } }
Схема подключения (правда без нарисованной сенсорной кнопки и вместо мосфета и жала паяльника стоит желтый светодиод): картинка кликабельна.
Надеюсь на вашу помощь
Хм, не сказал основного: все делается на Atmege32 (что было под рукой и не жалко)
На всякий случай прикрепляю архив. В нем библиотека сенсорной кнопки и необходимые файли для внедрения 32-меги в среду разработки:
http://forex4uplus.ru/arduino/ATmega32-Arduino-master.rar
CapSens работает, считая время, то есть через millis(). А у Вас сбиты настройки таймеров, совсем.
Перепишите настройки полностью из init() в wiring или пишите свою millшs() для нормальной работы capsens.
Ну, или, как вариан, перепишите для себя сенсор, если нет желания писать в экологической нише Ардуино.
Насколько я помню, там нужны millis(), delay(), delayMicroseconds(). И они ДОЛЖНЫ давать корректные значение, так как вся "фишка" в измерении времени.
Для меня это все пока что очень сложно... где искать эти init() и wiring?
Для меня это все пока что очень сложно... где искать эти init() и wiring?
???????
Пишите свою программу просто в Ардуино IDE и не трогайте таймер 0.
Библиотека сенсорной кнопки для Ардуино.
А можно ли прикрутить ШИМ к 0-му таймеру при этом больше ничего не трогая что бы не сбивать все остальные настройки системы?
0-вой таймер потому и задействовал что ШИМ-выходов на меге32 мало
Ну в ардуино же работает. Вот там и пишите все. Или копируйте настройки.
Дело в размерах. всю электронику хоче засенуть в ручку паяльника. Самая маленькая ПроМини довольно широкая, и ручка получится неудоная. Мега32 подходит, если все детали спаять прямо на ней.
0-вой таймер в ардуино вообще можно использовать? Ну хотябы вызывать прерывание по переполнению?
Так, ладно, попробуем уйти от 0-го таймера. Попробовал включить Watchdog таймер и использовать его в прерывании:
Не работает. Пробовал по- разному - никак! Что можете посоветовать? Как включить прерывание по Watchdog но без перезагрузки МК.
После многих експериментов оказалось что проблема была именно в настройках сенсорной кнопки -
temp1 = Sensor1.capSense(30);
// считываем значение с сенсорной кнопки (было касание / нет)
if
(temp1 > 80)
//
После первого нажатия сратывали ложные нажатия. Вместо 80 поставил 300 и все заработало даже с "неправильным" таймером.