Главная » Статьи » Swordfish

Очень интересный материал. Светодиоды в качестве кнопок. Видео!
Немного теории

Известно, что светодиод, как и фотодиод, а также любой выпрямительный диод, с точки зрения физики есть ничто иное, как сплав двух полупроводников P-типа и N-типа и являются по своей сути одним и тем же - диодом. Материал N-типа имеет в избытке электроны, имеющие отрицательный заряд, а материал P-типа - так называемые дырки(по другому - нехватка электронов), имеющие положительный заряд. Таким образом, ток в проводнике возникает под воздействием движения дырок в материале P-типа и электронов в материале N-типа. Когда создают спай из двух этих материалов, то часть электронов из материала N-типа устремляется в сторону материала P-типа, компенсируя нехватку электронов в нем. Аналогично, принято так называть, дырки из материала P-типа устремляются в сторону материала N-типа, создавая баланс в нем. На переходе между двумя этими материалами образуется слой, в котором не преобладают ни электроны, ни дырки, исключая проводимость самого перехода. Эта область известна как область собственной проводимости или область I-типа. Эта область препятствует дальнейшей миграции дырок и электронов.
Чтобы получить ток через диод, нужно приложить разность потенциалов, которая увеличит приток электронов в область P и дырок в область N.
Если приложить большое напряжение, то его хватит для пробоя слоя собственной проводимости. Но если же приложить незначительный потенциал, то это просто приложит к слою дополнительный заряд или электростатическое натяжение. Если воздействовать в данный момент светом на эту I-область, то это вызовет взаимодействие атомов внутри слоя. При этом электроны, взаимодействуя с фотонами (атомами света) и вызывая, таким образом, протекание тока, пропорционального интенсивности падающего света (фототок).

Что нам это дает?

Для использования этого эффекта потребуется использовать небольшую уловку - поскольку фототок очень мал для того, чтобы быть детектированным АЦП PIC микроконтроллера, мы представим светодиод в качестве конденсатора. Таким образом, мы сместим диапазон измерений фототока в большую сторону, достаточную для обнаружения и измерения фототока. Смысл измерения будет заключаться в измерении степени заряда этого "конденсатора". Это потребует некоторых манипуляций со светодиодом, но это не страшно, я думаю. Для более быстрого разряда "конденсатора", мы подадим 0 на него и будем измерять напряжение на нем. На результат измерения будет влиять, помимо светового потока, также и тепловой шум и ток утечки светодиода. Результаты также варьируются от светодиода к светодиоду. Некоторые светодиоды лучше, некоторые - хуже. Красные - чувствительны практически ко всем цветам светового потока, синие - только к синему цвету. Белые - хуже всех, некоторые из них чувствительны только к УФ излучению. Естественно, прозрачный корпус светодиода даст лучшие результаты, чем цветной, который будет играть роль фильтра. Для использования в качестве кнопок гораздо удобнее применять светодиоды в SMD корпусах.

Методика измерения фототока

1). Зажечь светодиод - это полностью разрядит "конденсатор".
2). Зарядим наш "конденсатор", подав на анод ноль, а на катод - единицу на короткое время.
3). Переводим анод в режим измерения (порт - как вход АЦП) и меряем напряжение на нем. Получаем исходное значение. которое понадобится нам в дальнейшем.
4). Ожидаем короткое время для определения реакции на свет. Чем больше это время, тем чувствительней детектор. Не стоит делать слишком длинным эту паузу, поскольку при очень высокой чувствительности светодиод начнет реагировать на посторонние шумы.
5). Снова измеряем напряжение и вычитаем его из исходного, полученного при первом измерении. В результате получим условное значение фототока в данный момент.
Как это выглядит схемотехнически - анод светодиода подключаем к цифровому порту микроконтроллера, а катод к аналоговому. У меня получилось такая схема:








Программная реализация

Вот три программки, использующие данный эффект для разных применений:

Первая программа - используем данный эффект для установки каких-то флагов

Code

Device = 18F4550

Clock = 20 //Частота микроконтроллера

Include "ADC.bas" //Подключим библиотеку для работы с АЦП

Config  
MCLRE = OFF //Отключим MCLRE (я не стал припаивать резистор на плату)

Dim i, LightVal1, LightVal2, Raw1, Raw2, Raw3, Raw4 As Integer //Необходимые нам переменные
//i - рабочая переменная для пищалки
//Lightval1, LightVal2 - переменные, которые будут содержать значения фототока
//Raw1, Raw2, Raw3, Raw4 - переменные для рассчета значения фототока
Dim PressBit1, PressBit2 As Bit //Это переменные для демонстрации того, что
//с помощью светодиодов можно устанавливать какие-то режимы или флаги

//-----------------Подпрограмма опроса светодиодов-кнопок------------------------------
//сразу для двух светодиодов  
Sub ReadButton()
Low(PORTE.0) //Катод - в ноль
High (PORTC.1) //Анод - в единицу - зажгли светодиод
Low(PORTE.1) //То же самое
High (PORTC.2) //со вторым светодиодом
DelayMS(1) //Небольшая задержка
TRISE.0 = 1 //Переключаем в обратном направлении -  
Low (PORTC.1) //заряжаем "конденсатор"
TRISE.1 = 1 //Так же со вторым
Low (PORTC.2) //светодиодом
Raw1 = ADC.Read(5) //Читаем исходные показания первого светодиода
Raw3 = ADC.Read(6) //второго...
DelayUS(1600) //Задержка для детекции фототока  
Raw2 = ADC.Read(5) //Читаем конечные показания первого светодиода
Raw4 = ADC.Read(6) //второго...
TRISE.0 = 0 //Сразу можно подготовить к следующему измерению
TRISE.1 = 0
LightVal1 = Raw2 - Raw1 //Рассчитываем значения фототока для
LightVal2 = Raw4 - Raw3 //каждого светодиода
End Sub
//-------Подпрограмма генерации звука для подтверждения "нажатия кнопки"----------
Sub Beep()
For i = 1 To 400  
High(PORTC.0)
DelayUS(100)
Low(PORTC.0)
DelayUS(100)
Next
End Sub

//-------------------Начало основной программы------------------------------------
//-----------------Инициализация переменных---------------------------------------  
ADCON2 = %10000011 'Настроим АЦП для работы
ADCON1 = %00001000
TRISE = 0 // Настроим порты на выход
TRISC = 0 // Настроим порты на выход
PORTC = 0 // Выключим светодиоды для начала
PressBit1 = 0 // Сбросим наши флаги
PressBit2 = 0
i = 0 // Очистим переменную счетчика
Main:  

ReadButton() //Проверка "нажатия кнопок" (загораживания света перед светодиодом)
If LightVal1 >= 115 Then //Если обнаружено значительное изменение интенсивности
//света
{Это значение подобрано экспериментально.
оно варьируется в зависимости от условий и от
светодиода к светодиоду}
If PressBit1 = 1 Then  
PressBit1 = 0 //то переключаем наш первый экспериментальный бит
Else
PressBit1 = 1
EndIf
Beep()
EndIf
//------------то же самое для второго светодиода----------------------------
If LightVal2 >= 115 Then  
If PressBit2 = 1 Then
PressBit2 = 0
Else
PressBit2 = 1
EndIf
Beep()
EndIf
//---------------А здесь мы индицируем состояние соответствующего бита-------
//Естественно это может быть индикацией какого-нибудь запущенного или
//остановленного процесса  
If PressBit1 = 1 Then //Если было определено "нажатие", то  
High(PORTC.1) //Зажигаем тот светодиод, который был "нажат"
Else
Low(PORTC.1) //Гасим тот светодиод, который был "нажат"
EndIf
//То же самое и для второго светодиода  
If PressBit2 = 1 Then
High(PORTC.2)
Else  
Low(PORTC.2)
EndIf
DelayMS(130) //Задержка для того, чтобы можно было видеть результат
//если ее не будет - не будет видно - зажжен светодиод или нет
GoTo Main //Начинаем программу сначала


Вторая программка - использование данного эффекта для изменения какого-то абстрактного параметра

Code


Device = 18F4550

Clock = 20 //Частота микроконтроллера

//Подключим ЖКИ к PORTD
#option LCD_DATA = PORTD.4  
#option LCD_RS = PORTD.0
#option LCD_EN = PORTD.1

Include "ADC.bas" //Подключим библиотеку для работы с АЦП
Include "lcd.bas" //Подключим библиотеку для работы с ЖКИ
Include "convert.bas" //Подключим библиотеку преобразований

Config  
MCLRE = OFF //Отключим MCLRE (я не стал припаивать резистор на плату)

Dim i, j, LightVal1, LightVal2, Raw1, Raw2, Raw3, Raw4 As Integer //Необходимые нам переменные
//i - рабочая переменная для пищалки
//j - переменная для управления каким-то абстрактным параметром
//Lightval1, LightVal2 - переменные, которые будут содержать значения фототока
//Raw1, Raw2, Raw3, Raw4 - переменные для рассчета значения фототока
Dim PressBit1, PressBit2 As Bit //Это переменные для демонстрации того, что
//с помощью светодиодов можно устанавливать какие-то режимы или флаги

//-----------------Подпрограмма опроса светодиодов-кнопок------------------------------
//сразу для двух светодиодов  
Sub ReadButton()
Low(PORTE.0) //Катод - в ноль
High (PORTC.1) //Анод - в единицу - зажгли светодиод
Low(PORTE.1) //То же самое
High (PORTC.2) //со вторым светодиодом
DelayMS(1) //Небольшая задержка
TRISE.0 = 1 //Переключаем в обратном направлении -  
Low (PORTC.1) //заряжаем "конденсатор"
TRISE.1 = 1 //Так же со вторым
Low (PORTC.2) //светодиодом
Raw1 = ADC.Read(5) //Читаем исходные показания первого светодиода
Raw3 = ADC.Read(6) //второго...
DelayUS(1600) //Задержка для детекции фототока  
Raw2 = ADC.Read(5) //Читаем конечные показания первого светодиода
Raw4 = ADC.Read(6) //второго...
TRISE.0 = 0 //Сразу можно подготовить к следующему измерению
TRISE.1 = 0
LightVal1 = Raw2 - Raw1 //Рассчитываем значения фототока для
LightVal2 = Raw4 - Raw3 //каждого светодиода
End Sub
//-------Подпрограмма генерации звука для подтверждения "нажатия кнопки"----------
Sub Beep()
For i = 1 To 400  
High(PORTC.0)
DelayUS(100)
Low(PORTC.0)
DelayUS(100)
Next
End Sub

//-------------------Начало основной программы------------------------------------
//-----------------Инициализация переменных---------------------------------------  
ADCON2 = %10000011 // Настроим АЦП для работы
ADCON1 = %00001000
TRISE = 0 // Настроим порты на выход
TRISC = 0 // Настроим порты на выход
PORTC = 0 // Выключим светодиоды для начала
PressBit1 = 0 // Сбросим наши флаги
PressBit2 = 0
i = 0 // Очистим переменную счетчика

Main:  
ReadButton() //Проверим "нажатие кнопок"
//Если был перекрыт свет перед первым светодиодом  
If LightVal1 >= 100 Then  
Beep() //то пищим для звукового подтверждения
Inc(j) //и инкрементируем параметр
EndIf
//То же самое и со вторым
If LightVal2 >= 100 Then  
Beep() //то пищим для звукового подтверждения
Dec(j) //и инкрементируем параметр
EndIf

WriteAt (1,1, DecToStr(j)," " ) //Отобразим параметр
DelayMS(60) //Задержка для того, чтобы параметр  
//менялся не слишком быстро

GoTo Main //Начнем сначала


Третья программа - передача на компьютер по USB условных значений фототоков обоих светодиодов

Code


Device = 18F4550

Clock = 48 // Внешний кварц - на 20 МГц, внутренний - 48 МГц (FS USB)

#option LCD_DATA = PORTD.4
#option LCD_RS = PORTD.0
#option LCD_EN = PORTD.1  

Config
PLLDIV = 5,
CPUDIV = OSC1_PLL2,
USBDIV = 2,
FOSC = HSPLL_HS,
VREGEN = ON,
MCLRE = OFF

#option USB_DESCRIPTOR = "USBProjectDesc.bas"

Include "usbhid.bas" // Импорт модуля для работы с HID
Include "ADC.bas" //Подключим библиотеку для работы с АЦП
Include "lcd.bas" //Подключим библиотеку для работы с ЖКИ
Include "convert.bas" //Подключим библиотеку преобразований

Dim Buffer(32) As Byte //Массив байт для отправки данных по шине USB
Dim LightVal1, LightVal2, Raw1, Raw2, Raw3, Raw4 As Integer //Необходимые нам переменные
//Lightval1, LightVal2 - переменные, которые будут содержать значения фототока
//Raw1, Raw2, Raw3, Raw4 - переменные для рассчета значения фототока  

//Подпрограмма детекции "нажатия первой кнопки"  
Sub ReadButton1()
Low(PORTE.0) //Катод - в ноль
High (PORTC.1) //Анод - в единицу - зажгли светодиод
DelayMS(2) //Небольшая задержка
TRISE.0 = 1 //Переключаем в обратном направлении -  
Low (PORTC.1) //заряжаем "конденсатор"
Raw1 = ADC.Read(5) //Читаем исходные показания первого светодиода  
DelayMS(3) //Задержка для детекции фототока  
Raw2 = ADC.Read(5) //Читаем конечные показания первого светодиода  
TRISE.0 = 0 //Сразу можно подготовить к следующему измерению
LightVal1 = Raw2 - Raw1 //Рассчитываем значения фототока

End Sub

//Чтение фототока второго светодиода  
Sub ReadButton2()
Low(PORTE.1)
High (PORTC.2)
DelayMS(2)  
TRISE.1 = 1
Low (PORTC.2)
Raw3 = ADC.Read(6)
DelayMS(3)  
Raw4 = ADC.Read(6)  
TRISE.1 = 0
LightVal2 = Raw4 - Raw3
End Sub

//-------------------Начало основной программы------------------------------------
//-----------------Инициализация переменных---------------------------------------  
ADCON2 = %10000011 //Настроим АЦП для работы
ADCON1 = %00001000
TRISE = 0 // Настроим порты на выход
TRISC = 0 // Настроим порты на выход
PORTC = 0 // Выключим светодиоды для начала

// Подключаемся к шине USB

WriteAt (1,1, "Connection" ) //Отображаем текущий процесс на ЖКИ
DelayMS(1000) //Задержка для отображения

Repeat
Service //Ожидаем подключения со стороны компьютера
Until Attached

LCD.Cls //Очистим ЖКИ после подключения
WriteAt (1,1, "Connection OK" ) //И оповестим пользователя об этом
DelayMS(1000) //Задержка для отображения
LCD.Cls //Очистим дисплей

//Начнем основной цикл программы
While true

ReadButton1() //Считаем первую "кнопку"
ReadButton2() //Считаем вторую "кнопку"

Buffer(0) = LightVal1 //Загрузим текущие значения фототока
Buffer(1) = LightVal2 //в первые два байта массива для отправки по USB
WriteArray(Buffer,2) //Отправим данные
WriteAt (1,1,"LED1 - ", DecToStr(LightVal1)," ") //Отобразим их одновременно и
WriteAt (2,1,"LED2 - ", DecToStr(LightVal2)," ") //на индикаторе
DelayMS(200) //Задержка для отображения
Service //Процедура обслуживания шины
Wend


Вы можете посмотреть на видео, что из этого получилось.




Естественно, все это применимо и к Picbasic PRO и Proton+.

Изучайте, комментируйте, задавайте вопросы.

Похожие материалы: USB HID + Visual Basic 6, Работа с USB HID устройствами в среде PureBasic, Проектирование usb вольтметра в Proton IDE, USB HID термометр, usb easy hid для Proton+, Микроконтроллеры Microchip с аппаратной поддержкой USB, Прибор по физике для измерения механической силы воздействия света

Скачать программу-терминал для приема данных с исходниками можно здесь 

Статья написана по материалам сайтов http://www.protonbasic.co.uk/ и http://www.thebox.myzen.co.uk




Категория: Swordfish | Добавил: ADMIN (30.06.2011)
Просмотров: 11909 | Комментарии: 13 | Теги: светодиодные кнопки, свет, фотодетектор, led, статьи, USB, Swordfish, кнопки | Рейтинг: 5.0/9
Всего комментариев: 13
1 ivan_fd   (30.06.2011 13:44)
Очень интересная статья, спасибо!

2 ADMIN   (30.06.2011 15:57)
Спасибо. Старался. Кстати, программа-терминал - на Delphi. Если надо - добавлю к статье. Там - поле для воображения.

4 ivan_fd   (30.06.2011 16:58)
Quote
Кстати, программа-терминал - на Delphi. Если надо - добавлю к статье. Там - поле для воображения.


Добавьте, интересно посмотреть.
Спасибо!

3 Matrix252005   (30.06.2011 16:04)
ADMIN, хорошая работа!!! У меня такая же плата, только с PIC16F887 на борту... Круто!!! Спасибо!

5 ADMIN   (30.06.2011 17:04)
Ну завтра загружу все исходники, сегодня на работе флешку забыл

6 mikhail09p   (03.07.2011 18:16)
Класс! wacko Бум разбиратся!

7 ADMIN   (04.07.2011 07:01)
Спрашивайте, если что

8 retas   (17.10.2011 16:32)
Предлагаю, однако, стараться вещи называть своими именами - здесь датчик, сенсор, и ни какая ни кнопка ибо нажимать ничего не надо. А то я и так и сяк гляжу, где там пружинка какая, че там замыкается, монитор кручу да переворачиваю чтоб со всех сторон разглядеть и всё безтолку!

9 ADMIN   (17.10.2011 18:10)
я не называю светодиоды кнопками. Из названия видно, что светодиоды играют роль кнопок. По крайней мере, в моей статье они используются в этом качестве

10 swq25   (09.11.2011 10:13)
Подскажите , где взять файл USBProjectDESC.Inc ????

11 ADMIN   (12.11.2011 06:38)
Этот файл создается с помощью EasyHid. В статье указаны ссылки - USB HID + Visual Basic 6. Почитай там об этом

12 freeeeedom400   (28.05.2012 23:01)
Очень интересно!

0
13 ADMIN   (26.11.2014 05:05)
Ну что? Есть результаты у кого-то по этой статье?

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]