Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры ARM, Cortex, STM32
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.94/65: Рейтинг темы: голосов - 65, средняя оценка - 4.94
Багдин
0 / 0 / 0
Регистрация: 08.06.2015
Сообщений: 64
1

Ёмкостный датчик касаний на STM32

12.06.2015, 01:43. Просмотров 11782. Ответов 14
Метки нет (Все метки)

емкостной сенсор на базе stm32f103vet
Конечная цель - что-то похожее на разработку Виктора Тимофеева:http://www.pic24.ru/doku.php/oso/articles/pk2_oso_piano?do=backlink
сначала стараюсь сделать чтобы все работало с одним сенсором и ничего не получается, возможно кто-то подскажет что и где я уже делаю не так_)) Буду очень рад любым указаниям на мои косяки.
Код
void Delay(volatile uint32_t nCount)
{
for (; nCount != 0; nCount--);
}
GPIO_InitTypeDef GPIO_InitStructure;
void RCC_Confikurotion(void);
int main(void){
RCC_Confikurotion();

while (1)
{
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);

//AIN(PC0)  выход "0" Push-pull, DOUT(PC5) Push-pull в "0"
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);

GPIO_RisetByts(GPIOC, GPIO_Pin_5);
GPIO_RisetByts(GPIOC, GPIO_Pin_0);
Delay(0xAFFFF);

uint32_t count=0;
//DOUT(PC5) Push-pull в "1", а AIN(PC0) настраиваем как аналоговый вход Analog
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);

//цикл (поки AIN(PC0)не "1")

while(!GPIO_ReadInputDataByt(GPIOC, GPIO_Pin_0)){
GPIO_SetByts(GPIOC, GPIO_Pin_5);

count++;

}

if(count>1){
GPIO_SetByts(GPIOD, GPIO_Pin_3);
Delay(0xAFFFF);
GPIO_RisetByts(GPIOD, GPIO_Pin_3);
//звіряємо данні

}
}
}

void RCC_Confikurotion(void)
{
SystemInit();

RCC_APB2PeriphClockCmd( RCC_APB2Periph_USORT1 |RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |
RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD |
RCC_APB2Periph_GPIOE, ENABLE);
}
<Изображение удалено>
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.06.2015, 01:43
Ответы с готовыми решениями:

Stm32 датчик освещенности библиотека unix_time
Добрый день, есть проект датчика освещенности, которое перед прошивкой надо было все параметры...

stm32 + hc-sr04 Ультразвуковой датчик расстояния [решение]
&quot;Спойлер&quot;Особо не пинайте, первая попытка преподнести народу полезную информацию. Если есть...

Несколько касаний
Делаю пианино. Всё сделал, но работает только на 1 касание. Я понял что у меня по сути как мышь....

Подключение к Arduino UNO 4-х вентиляторов + датчик воды + датчик грунта
Добрый день. Прошу помочь. Требуется подключить к Arduino UNO 4 вентилятора (куллер комп....

СМ Bosch wtb86211 oe/ 01, Определить датчик влажности и датчик температуры
Добрый день. СМ пытался сделать какой то мастер и исчез вместе с датчиком влажности и датчиком...

14
judshym
1 / 1 / 0
Регистрация: 03.02.2011
Сообщений: 382
12.06.2015, 14:53 2
зачем АЦП?
алгоритм очень похож на статью: http://habrahabr.ru/post/132739/
этот алгоритм сам проверял, работает на stm32f050 48МГц
0
Багдин
0 / 0 / 0
Регистрация: 08.06.2015
Сообщений: 64
12.06.2015, 15:03 3
Цитата Сообщение от judshym
зачем АЦП?
... в конечный результате это должна выйти матрица из таких емкостных участков поэтому я стараюсь сначала сделать такой трюк с двумя выводами контроллера и одной "кнопкой", а когда выйдет то пытаться подсоединить все через диоды в матрицу как это сделаноhttp://www.pic24.ru/doku.php/oso/articles/pk2_oso_piano?do=backlink
0
Багдин
0 / 0 / 0
Регистрация: 08.06.2015
Сообщений: 64
12.06.2015, 15:06 4
Цитата Сообщение от judshym
алгоритм очень похож на статью: http://habrahabr.ru/post/132739/
спасибо, попробую повторить, заодно проверю насколько у меня кривые руки_)))))))))
0
OVY-srok
0 / 0 / 0
Регистрация: 26.03.2015
Сообщений: 316
12.06.2015, 15:42 5
Зачем такие сложности...
Конфиг лапы - выход с открытым коллектором и подтяжка на +. Лапа подключается через сборку диодов, например BAV99 , и ёмкость стабильной группы 300p-1n.
Алгоритм очень простой - весь порт в ноль, запуск таймера, весь порт в 1, таймер сработал - читаем порт. Нуль - это "нажатая кнопка", для надёжности фильтрация состояния кнопки, на 10-300 отчётов.
0
Багдин
0 / 0 / 0
Регистрация: 08.06.2015
Сообщений: 64
12.06.2015, 16:09 6
Цитата Сообщение от OVY-srok
Зачем такие сложности...
Конфиг лапы - выход с открытым коллектором и подтяжка на +. Лапа подключается через сборку диодов, например BAV99 , и ёмкость стабильной группы 300p-1n.
а можно как то подробней, для ... непосвященных_))))????? всё должно опрашиваться по столбцам и линейкам, иначе как тогда сделать много кнопок ?
0
OVY-srok
0 / 0 / 0
Регистрация: 26.03.2015
Сообщений: 316
12.06.2015, 18:27 7
Цитата Сообщение от Багдин
всё должно опрашиваться по столбцам и линейкам, иначе как тогда сделать много кнопок
Боюсь огорчить, но простая ёмкостная кнопка не может работать в матрице. Весь её алгоритм - это заряд-разряд ёмкости через изолятор.
Для того чтобы емкостный сенсор мог работать в матрице - необходим быстрый оу, с минимальной емкостью на входе. Идеально - когда ёмкость входа не превышает конструктивную ёмкость корпуса. Потому как узел должен будет улавливать разницу в ёмкости между 500р<->505р. Для этих целей специально изобретают чипы, для сенсорных экранов. Там и температурная компенсация, и стабы питающие усилители, и таблица констант для каждого сегмента сенсорной матрицы, и автоматический алгоритм самокалибровки... Вообщем дофига всего - чего в россыпи повторить практически невозможно.
В домашнем варианте доступен вариант с одной ёмкостной кнопкой на одной лапе. BAV99 - требуется для защиты мк от статики, включается на между землёй - лапой - питанием мк, на питание стабилитрон - обязательное условие, между лапой и сенсором ёмкость от 300р до 1n - условие, ёмкость должна быть из термостабильной группы NР0 http://www.compel.ru/FLzB6 . На сам сенсор необходимо защитить от влаги и механических повреждений со стороны пользователя , а так-же земляным полигоном с обратной стороны ПП сенсора.
Частота опроса кнопки зависит от получившейся ёмкости, в среднем от 1кгц до 500кгц.
0
Багдин
0 / 0 / 0
Регистрация: 08.06.2015
Сообщений: 64
12.06.2015, 20:05 8
Цитата Сообщение от OVY-srok
Потому как узел должен будет улавливать разницу в ёмкости между 500р<->505р. Для этих целей специально изобретают чипы... и таблица констант для каждого сегмента сенсорной матрицы, и автоматический алгоритм самокалибровки... .
Я хочу это повторить, и у меня уже почти все выходит, только проблемы с алгоритмом самокалибровки ново опрошенных данных, пока у меня позитивный настрой, посмотрим так ли это невозможно
Код
void Delay(volatile uint32_t nCount)
{
for (; nCount != 0; nCount--);
}
GPIO_InitTypeDef GPIO_InitStructure;
void RCC_Confikurotion(void);
int main(void){
RCC_Confikurotion();

while (1)
{
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);

//AIN(PC0)  выход "0" Push-pull, DOUT(PC5) Push-pull в "0"
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);

GPIO_RisetByts(GPIOC, GPIO_Pin_5);
GPIO_RisetByts(GPIOC, GPIO_Pin_0);
Delay(0xAFFFF);

uint32_t count=0;
//DOUT(PC5) Push-pull в "1", а AIN(PC0) настраиваем как аналоговый вход Analog
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);

//цикл (поки AIN(PC0)не "1")

while(!GPIO_ReadInputDataByt(GPIOC, GPIO_Pin_0)){
GPIO_SetByts(GPIOC, GPIO_Pin_5);

count++;

}

if(count>1){
GPIO_SetByts(GPIOD, GPIO_Pin_3);
Delay(0xAFFFF);
GPIO_RisetByts(GPIOD, GPIO_Pin_3);
//звіряємо данні

}
}
}

void RCC_Confikurotion(void)
{
SystemInit();

RCC_APB2PeriphClockCmd( RCC_APB2Periph_USORT1 |RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |
RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD |
RCC_APB2Periph_GPIOE, ENABLE);
}
здесь пока опрос одной кнопки и нужно ещё как-то разобраться с частотой (кажется если ее поднять то все будет работать чувствительнее от того что счетчик нащелкает за то же время больше тактов) кто знает как задействовать наружный кварц на 8 герц??????? чтобы по максимуму быстро...
0
OVY-srok
0 / 0 / 0
Регистрация: 26.03.2015
Сообщений: 316
12.06.2015, 21:56 9
Я не пользуюсь стандартными библиотеками, уже успел забыть - чего там делается. Но тут нету алгоритма, который может опросить сенсорную кнопку...
Назови название чипа.
0
Багдин
0 / 0 / 0
Регистрация: 08.06.2015
Сообщений: 64
12.06.2015, 22:15 10
Цитата Сообщение от OVY-srok
Назови название чипа.
емкостной сенсор на базе stm32f103vet
0
mShit
0 / 0 / 0
Регистрация: 12.08.2012
Сообщений: 1,217
12.06.2015, 22:39 11
Библиотека Qtouch от Atmel позволяет делать и матрицы ёмкостных сенсоров и слайдеры. Там принцип немного другой - кнопка состоит из двух электродов, на один из них подаётся меиндр, а к другому подключен семплирующий конденсатор, причём между двумя ножками МК. Эти ноги синхронно с меиндром прерключаются с высокоомного входа на выход с низким уровнем в противофазе, при этом заряд с первого электрода постепенно переносится в семплирующий конденсатор через ёмкость между электродами кнопки. При прикосновении часть поля шунтируется пальцем и семплирующий конденсатор заряжается медленнее. По этому критерию и определяется факт прикосновения.
0
OVY-srok
0 / 0 / 0
Регистрация: 26.03.2015
Сообщений: 316
13.06.2015, 00:48 12
Цитата Сообщение от Багдин
Цитата Сообщение от OVY-srok
Назови название чипа.
емкостной сенсор на базе stm32f103vet

Наверное примерно так - матрица 8*8 , по одной строке колбасим верх-низ с разным временем, опрашиваемая кнопка (линия) должна по идее перейти за барьер логической единицы - в случае если не будем ей мешать. Кнопки по порядку в массиве knopka.
Код
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
GPIOE->CRL = 0x22222222; //GPIOE 0-7  max speed 2 MHz. output push-pull.
GPIOE->CRH = 0x66666666; //GPIOE 8-15 max speed 2 MHz. output Open-drain.
const uint32_t strob[11] ={
0x00FE0001; // первая строка GPIOE 0 = 1               //0
0x00FD0002;
0x00FB0004;
0x00F70008;
0x00EF0010;
0x00DF0020;
0x00BF0040;                                             //6
0x007F0080; // восьмая строка GPIOE 7 = 1               //7
0x00FF0000; // строчки в ноль GPIOE0-7 =0               //8
0x0000FF00; // столбцы в единицу - накопление GPIOE8-15 //9
0xFF000000; // столбцы в ноль - обнуление GPIOE8-15     //10
}

inline void Delay(volatile uint32_t time_tmp){ while ( time_tmp-- );}

uint8_t knopka [64];
#define tici     300 // от балды - но влияет на скорость опроса

void opros (void)
{
uint32_t tmp1;
uint32_t tmp2;
uint32_t tmp3;
uint32_t tmp4;
for (tmp1 = 0 ;tmp1 < 8; tmp1++)
{
GPIOE->BSRR = strob[10];
GPIOE->BSRR = strob[8];
Delay(tici);
GPIOE->BSRR = strob[9];
for (tmp2=0;tmp2<32;tmp2++)
{
GPIOE->BSRR = strob[8];
Delay(tici);
GPIOE->BSRR = strob[(tmp1)];
Delay((tici / 2));
}
tmp3 = (GPIOE->IDR) >> 8;
for (tmp2=0;tmp2<8;tmp2++)
{
tmp4 = tmp3 & strob[tmp2];
if (tmp4 > 0) knopka[((tmp1 * 8)+ tmp2)] = 1;  else knopka[((tmp1 * 8)+ tmp2)] = 0;
}
}

}
0
Багдин
0 / 0 / 0
Регистрация: 08.06.2015
Сообщений: 64
14.06.2015, 20:43 13
УРА !!!! спасибо всем_)))) одна бессонная ночь и все получилось. Код написан очень легко, с комментариями для удовольствия чтения.
Схема подключения такая как я приводил в первом моем посте (http://www.pic24.ru/doku.php/oso/articles/pk2_oso_piano?do=backlink), реализовано три DOUT на один AIN. Алгоритм калибровки на днях выложу, ещё тестирую.
Код
#include "stm32f10x.h"
void Delay(volatile uint32_t nCount){
for (; nCount != 0; nCount--);
}
GPIO_InitTypeDef GPIO_InitStructure;
void RCC_Confikurotion(void);
void Confikurotion1(void);//розряд
void Confikurotion2(void);//заряд-зчитування
int main(void){
RCC_Confikurotion();
uint32_t count=0;

//////dyodiki///////////////////
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
///////////////////////////////////
while (1){
//rozrazaem
Confikurotion1();

GPIO_RisetByts(GPIOC, GPIO_Pin_2);
GPIO_RisetByts(GPIOC, GPIO_Pin_5);
GPIO_RisetByts(GPIOC, GPIO_Pin_3);
//zarazaem
Confikurotion2();
count=0;

GPIO_SetByts(GPIOC, GPIO_Pin_5);
while(!GPIO_ReadInputDataByt(GPIOC, GPIO_Pin_0)){ count++;}//цикл (поки AIN(PC0)не "1")

if(count>3){ GPIO_SetByts(GPIOD, GPIO_Pin_3);}
//звіряємо данні
if(count<3){GPIO_RisetByts(GPIOD, GPIO_Pin_3);}
//rozrazaem
Confikurotion1();

GPIO_RisetByts(GPIOC, GPIO_Pin_5);
GPIO_RisetByts(GPIOC, GPIO_Pin_2);
GPIO_RisetByts(GPIOC, GPIO_Pin_3);

//zarazaem
Confikurotion2();
count=0;
GPIO_SetByts(GPIOC, GPIO_Pin_2);
while(!GPIO_ReadInputDataByt(GPIOC, GPIO_Pin_0)){ count++;}//цикл (поки AIN(PC0)не "1")

if(count>3){ GPIO_SetByts(GPIOD, GPIO_Pin_6);
Delay(0xAFFFF);
GPIO_RisetByts(GPIOD, GPIO_Pin_6);}//звіряємо данні
//rozrazaem
Confikurotion1();

GPIO_RisetByts(GPIOC, GPIO_Pin_5);
GPIO_RisetByts(GPIOC, GPIO_Pin_2);
GPIO_RisetByts(GPIOC, GPIO_Pin_3);

//zarazaem
Confikurotion2();
count=0;
GPIO_SetByts(GPIOC, GPIO_Pin_3);
while(!GPIO_ReadInputDataByt(GPIOC, GPIO_Pin_0)){ count++;}//цикл (поки AIN(PC0)не "1")

if(count>3){ GPIO_SetByts(GPIOB, GPIO_Pin_5);
Delay(0xAFFFF);
GPIO_RisetByts(GPIOB, GPIO_Pin_5);}//звіряємо данні
}

}

void Confikurotion1(void){
// DOUT Push-pull
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_2| GPIO_Pin_0|GPIO_Pin_5|GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);

}
void Confikurotion2(void){
// а AIN(PC0) настраиваем как аналоговый вход Analog
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
}

void RCC_Confikurotion(void)
{
SystemInit();
RCC_APB2PeriphClockCmd( RCC_APB2Periph_USORT1 |RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |
RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD |
RCC_APB2Periph_GPIOE, ENABLE);
}
Спасибо всем кто откликнулся, но проблема у меня остается с тем, что я не знаю как передать данные по юсб в комп, вернее чтобы когда я подключал по юсб контроллер он определялся как HID устройство (клавиатура). Поможете???????
0
foxmim
0 / 0 / 0
Регистрация: 13.04.2012
Сообщений: 38
15.06.2015, 17:13 14
Возьмите лучше STM32F303 - в нем встроенный контроллер TSC есть.
надо выбирать контроллер под задачу а не наоборот.
0
Багдин
0 / 0 / 0
Регистрация: 08.06.2015
Сообщений: 64
15.06.2015, 19:03 15
Цитата Сообщение от foxmim
Возьмите лучше STM32F303 - в нем встроенный контроллер TSC есть.
надо выбирать контроллер под задачу а не наоборот.
не могу, нужно на этом, так я написал ещё с самого начала, да и мой ничем не хуже подходит под эту задачу
0
15.06.2015, 19:03
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
15.06.2015, 19:03

Помогите со схемой.Нужен датчик удара и датчик прикосновения
Купил дешёвую сигнализацию, время попользовался, теперь хочется доработать. В электроники я так...

Обработка касаний в SurfaceView
Всем привет! Для обработки касаний в surfaceview определяю OnTouchEvent () но касания не...

Atmega + датчик освещенности. Помогите подобрать датчик
Хочу измерять освещенность внутри теплицы и на улице. Посоветуйте датчик освещенности и может есть...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru