Перейти к блогу GetChip.net - блог        JilTE[1] - в разработке     Модификации устройств - модификации

 
Текущее время: 21 июл 2019, 13:16

Часовой пояс: UTC + 3 часа [ Летнее время ]



Начать новую тему Ответить на тему  [ Сообщений: 58 ]  На страницу Пред.  1, 2, 3, 4, 5, 6
Автор Сообщение
 Заголовок сообщения: Re: Простая сенсорная панель (Keypad).
СообщениеДобавлено: 11 дек 2015, 01:38 
Не в сети

Зарегистрирован: 05 апр 2012, 09:14
Сообщения: 7
Благодарю! Честно.
я уже две неделю воюю с этим. не даётся. я сделал автокалибровку: при запуске опрашивается каждая кнопка и потом нажатие сверяется с этим значением. и всё равно какие-то кнопки не реагируют на нажатие а какие-то черезчур чувствительны.
сделал проверку нажатия кнопки(триггер) и не работает.
про отсылку символов вообще молчу. шлётся всё что угодно кроме символа нажатой клавиши.
может подскажете что не так с логикой? пожалуйста. очень обино за две убитых впустую недели(((
Код:
#include <avr/io.h>
#include <avr/interrupt.h>
#include "usart.h"
#include "usart.c"


//макросы для работы с битами
#define InvBit(reg, bit)        reg ^= (1<<(bit))
#define ClearBit(reg, bit)       reg &= (~(1<<(bit)))
#define SetBit(reg, bit)         reg |= (1<<(bit))   
#define BitIsSet(reg, bit)     ((reg &  (1<<bit)) != 0)

/*
//переменные для подсчета количества переполнений
volatile unsigned char sub_time_pin0 = 0;

unsigned char CountDreb;
//сколько циклов опроса кнопка должна удерживаться

*/
// количество сенсоров
#define SENSOR 10 //10.
//  переменная счётчик сенсорных площадок
volatile unsigned char _iSens;
// переменная счётчик
volatile unsigned char _Counter;
// массив данных калибровки выводов
volatile unsigned char Kalibrovka[SENSOR];
//переменная для антидребезга
//volatile unsigned char _DrebComp = 0;
//#define _Drebezg 20
// перемменная нажатия клавиши
volatile unsigned char _PressedSensor[SENSOR];
//проверка нажатия кнопки через структуру где numb - переменная цикла
#define Clear_DDR(numb)         ( *(VirtPIN[numb].DDR_BUT) &=  (~(1<<VirtPIN[numb].BUT)) )       // вывод работает как ВХОД. при PORT = 0 = HI-Z
#define Set_DDR(numb)         ( *(VirtPIN[numb].DDR_BUT) |=  (1<<VirtPIN[numb].BUT) )         // вывод работает на ВЫХОД. PORT = 0 = pin = 0
#define Check_PIN(numb)         ( (*(VirtPIN[numb].PIN_BUT)&(1<<VirtPIN[numb].BUT))!=0 )       
#define UART_PIN(numb)         (VirtPIN[numb].Symbol)
// структура/массив пинов сенсорных площадок
struct _STRUCT_PIN     
{
   volatile   unsigned char   *DDR_BUT;         //порт кнопки   (DDRD, DDRA...)
   volatile   unsigned char   *PIN_BUT;         //порт кнопки   (PIND, PINA...)
   volatile   unsigned char   BUT;              //пин кнопки   (PD0, PA1...)
   volatile   unsigned char   Symbol;         // символ по уарту
};

struct _STRUCT_PIN  VirtPIN[SENSOR] =
{
   {&DDRD,&PIND,PD6,'0'},//9
   {&DDRD,&PIND,PD3,'1'},//7
   {&DDRB,&PINB,PB1,'2'},//1
   {&DDRB,&PINB,PB4,'3'},//4
   {&DDRD,&PIND,PD2,'4'},//6
   {&DDRB,&PINB,PB0,'5'},//0
   {&DDRB,&PINB,PB3,'6'},//3
   {&DDRD,&PIND,PD4,'7'},//8
   {&DDRB,&PINB,PB2,'8'},//2
   {&DDRB,&PINB,PB5,'9'},//5
//   {&DDRD,&PIND,PD5,'L'},//10      //<--- нет 1Мом резистора на выводе
//   {&DDRB,&PINB,PB6,'R'} //11      //<--- нет 1Мом резистора на выводе
};

int main( void )
{
  // инициализация пинов контроллера для работы с сенсорными площадками
  // устанавливаем выводы на выход (DDR = 1) и в устанавливаем ноль (PORT = 0)
   DDRD  |= (1<<PD2)|(1<<PD3)|(1<<PD4)|(1<<PD6);
   PORTD &= (1<<PD2)&(1<<PD3)&(1<<PD4)&(1<<PD6);
   DDRB  |= (1<<PB0)|(1<<PB1)|(1<<PB2)|(1<<PB3)|(1<<PB4)|(1<<PB5);
   PORTB &= (1<<PB0)&(1<<PB1)&(1<<PB2)&(1<<PB3)&(1<<PB4)&(1<<PB5);
   USART_Init();

   //   USART_SendStr("Button: ");
   
// калибровочная часть НАЧАЛО
// выполняется один раз после инициализации периферии
sei();
//++++++++++++++++++++++++++++++++++++++++++++++++++
for (_iSens=0; _iSens<SENSOR; _iSens++)
    {
      Set_DDR(_iSens);                       // сбросили ёмкость на сенсоре
      _Counter = 0;                        // обнулили счётчик
      Clear_DDR(_iSens);                     // начали заряжать ёмкость сенсорной площадки
      while(!Check_PIN(_iSens) && (_Counter < 0xFF) )            // инкременировать счётчик до тех пор пока не выйдет из нуля в единицу. значит ёмкость зарядилась
      {
         _Counter++;                     // проверка счётчика. если счётчик равен ff значит пин контроллера и ёмкость сенсорной площадки калибровку не прошли. а значит бида-бида.
      }      
      Set_DDR(_iSens);                     // сбросили ёмкость на сенсоре и переходим к следующему сенсору
      Kalibrovka[_iSens]=_Counter++;            // сохранили показание счётчика в массиве калибровки. с этими значениями будет проверяться нажата "кнопка или нет"
      
      USART_SendStr(_Counter);
    }
//++++++++++++++++++++++++++++++++++++++++++++++++++
// калибровочная часть КОНЕЦ
//разрешаем прерывания 




  while(1)
  {
    
        //  рабочая часть НАЧАЛО
//++++++++++++++++++++++++++++++++++++++++++++++++++   

    for (_iSens=0; _iSens<SENSOR; _iSens++)    
    {
      cli();
      if (Kalibrovka[_iSens]<0xFF)                //  проверка массива калибровки на 0xFF. если равно то пин не фурычит
      {
         Set_DDR(_iSens);                       // сбросили ёмкость на сенсоре
         _Counter = 0;                        // обнулили счётчик
         Clear_DDR(_iSens);                     // начали заряжать ёмкость сенсорной площадки
         while(!Check_PIN(_iSens) && (_Counter < 0xFF))            // инкременировать счётчик до тех пор пока не выйдет из нуля в единицу. значит ёмкость зарядилась
         {
            _Counter++;                     // проверка счётчика. если счётчик равен ff значит пин контроллера и ёмкость сенсорной площадки калибровку не прошли. а значит бида-бида.
         }      
      if ( (_Counter > Kalibrovka[_iSens]) && !( _PressedSensor[_iSens] ) )      // сравниваем счётчик со значениями из массива калибровки.
         {                                                      // если значение калибровки меньше то (1)
            _PressedSensor[_iSens] = 1;                                 //переменная нажатия кнопки = НАЖАТА
            USART_SendStr(UART_PIN(_iSens));                            // (1) то отсылаем код кнопки по уарту.
         }
         
      if ( (_Counter <= Kalibrovka[_iSens]) && ( _PressedSensor[_iSens] ) )      // сравниваем счётчик со значениями из массива калибровки.
         {
            _PressedSensor[_iSens] = 0;
         }

      
         Set_DDR(_iSens);                                          // сбросили ёмкость на сенсоре. он больше нам не нужен
         //шагаем на следующий пин
      }      
      sei();
    }
//++++++++++++++++++++++++++++++++++++++++++++++++++   
//  рабочая часть КОНЕЦ
  }   

  return 0;
  }






Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Простая сенсорная панель (Keypad).
СообщениеДобавлено: 12 дек 2015, 00:42 
Не в сети
Администратор
Аватара пользователя

Зарегистрирован: 15 май 2011, 23:00
Сообщения: 1925
Какие эталонные значения сенсоров выходят?
Какие значения при прикосновении?

Я не вижу в программе, что сенсоры для каждого замера опрашиваются по несколько раз, а значения усредняется


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Простая сенсорная панель (Keypad).
СообщениеДобавлено: 12 дек 2015, 18:30 
Не в сети

Зарегистрирован: 05 апр 2012, 09:14
Сообщения: 7
измеряется всё один раз при инициализации. измеряется в количестве тактов цикла while и и сохраняется в оперативной памяти. в отладке эти значения отправляются по уарту. большинство из них больше байта - FF. видимо опрос слишком быстрый.
значения при прикосновении больше FF стабильно.
видимо надо "загрубить" цикл while - чтобы точки замера разнести во времени.
усреднения нет - не могу сообазить как сделат чобы не вылезти из объёмов оперативной памяти.

а так что нужно будет сделать - цикл for от 0 до 32 для каждой клавиши, каждый раз суммировать значение замера и потом сумму разделить на 32.
сам цикл замера увеличить во времени чтобы не был слишком шустрым...
поправьте меня если не прав.


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Простая сенсорная панель (Keypad).
СообщениеДобавлено: 12 дек 2015, 19:33 
Не в сети
Администратор
Аватара пользователя

Зарегистрирован: 15 май 2011, 23:00
Сообщения: 1925
Да, все правильно.
Усреднений можно и 8 сделать - уже будет лучше.

Какие все таки значения с сенсоров?


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Простая сенсорная панель (Keypad).
СообщениеДобавлено: 12 дек 2015, 20:10 
Не в сети

Зарегистрирован: 05 апр 2012, 09:14
Сообщения: 7
GetChiper писал(а):
Да, все правильно.
Усреднений можно и 8 сделать - уже будет лучше.

Какие все таки значения с сенсоров?

их нет(( какпробовал снять но не получается - код отсылающий значения по уарту через кольцевой буфер шлёт фигню. а так - наверняка больше FF. а поскольку счётчик переполняется то регистрируется нажатие


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Простая сенсорная панель (Keypad).
СообщениеДобавлено: 01 янв 2016, 21:35 
Не в сети

Зарегистрирован: 05 апр 2012, 09:14
Сообщения: 7
всех с наступившим!
не поверите - оказывается на точность измерения и работу алгоритма в целом сильно влиял код буфера для уарта! сейча только, после перерыва и работой над другой железкой, понял что то код для буфера уарта что я использовал сильно косячен. сейчас разбираюсь в подробностях и отпишу о результатах по завершению.


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Простая сенсорная панель (Keypad).
СообщениеДобавлено: 24 апр 2016, 22:48 
Не в сети

Зарегистрирован: 13 мар 2016, 16:57
Сообщения: 3
Собрал модификацию устройства: выбросил индикацию (как звук, так и светодиоды), за счёт этих выводов увеличил количество линий до 16. Пришлось убрать даже ввод UART, теперь нет сохранения в память значений чувствительности линий. И остался только вывод символа нажатой линии, ну и отладочная информация при старте. Увеличил счётчик повторов, чтобы второе срабатывание не мешалось.
Заодно развёл плату под SMD. Правда, получилось совместно с говорилкой из 87-го проекта.


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Простая сенсорная панель (Keypad).
СообщениеДобавлено: 25 апр 2016, 22:28 
Не в сети
Администратор
Аватара пользователя

Зарегистрирован: 15 май 2011, 23:00
Сообщения: 1925
Отлично!
Можно оставить в разделе модов - другим может пригодится!
viewforum.php?f=24


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 58 ]  На страницу Пред.  1, 2, 3, 4, 5, 6

Часовой пояс: UTC + 3 часа [ Летнее время ]


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 6


Вы не можете начинать темы
Вы можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB