This shows you the differences between two versions of the page.
| pt:examples:digi:switch [2015/12/09 19:53] – Criação deste novo documento. artica | pt:examples:digi:switch [2020/07/20 12:00] (current) – external edit 127.0.0.1 | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | ====== Interruptores ====== | ||
| + | // | ||
| + | [HW] [[en: | ||
| + | [AVR] [[en: | ||
| + | [LIB] [[en: | ||
| + | [PRT] [[en: | ||
| + | |||
| + | ===== Teoria ===== | ||
| + | |||
| + | Um interruptor é um dispositivo eletromecânico que pode conectar ou interromper o circuito elétrico. Existem muitos tipos diferentes de interruptores; | ||
| + | |||
| + | Interruptores são habitualmente usados para electrificação de circuitos eléctricos, | ||
| + | |||
| + | Diferentes símbolos esquemáticos são utilizados para identificar diferentes tipos de interruptores. Em baixo estão exemplos de típicos interruptores elétricos usados em desenhos elétricos com os seus símbolos: | ||
| + | |||
| + | ^ Interruptor de botão ^ Interruptor Toggle ^ Interruptor Rocker ^ Interruptor Micro ^ Interruptor DIL ^ | ||
| + | |{{: | ||
| + | | {{: | ||
| + | |||
| + | A fim de utilizar um interruptor como um sensor ligado a um microcontrolador, | ||
| + | |||
| + | [{{ : | ||
| + | [{{ : | ||
| + | |||
| + | As interferências complicam o uso de interruptores. O método mais comum para evitar os resultados indeterminados é conectar a entrada de microcontrolador à terra ou através de uma resistência. Uma resistência para esta função é chamada resistência pull-down ou pull-up. Normalmente, | ||
| + | |||
| + | Um interruptor simples de dois contactos pode ser usado como um sensor com resistência pull-up ou pull-down, o interruptor connecta a entrada com uma e a resistência ao outro potencial. Normalmente os microcontroladores têm incorporado opções de resistência pull-up ou pull-down; portanto, não há necessidade de se adicionar uma resistência ao circuito. Por exemplo, microcontroladores AVR tem resistências 20 kΩ – 50 kΩ pull-up nos seus pinos IO. | ||
| + | |||
| + | Deve ser mencionado que, interruptores mecânicos têm um problema adicional - salto do interruptor. Isso faz com que várias curtas má ligações no momento da conexão. Deve-se ressaltar, que os exemplos usados neste capítulo não são afetados pelo salto de interruptor e que o assunto será abordado com mais detalhes no próximo capítulo. | ||
| + | |||
| + | <code c> | ||
| + | // Homelab User interface board button test code | ||
| + | #include < | ||
| + | |||
| + | // Main program | ||
| + | int main(void) | ||
| + | { | ||
| + | // Set LED pins as output and switch pins as input | ||
| + | pin_setup_output(led_green); | ||
| + | pin_setup_input(S1); | ||
| + | |||
| + | // Endless loop | ||
| + | while (1) | ||
| + | { | ||
| + | // green LED turns on when switch S1 is pressed | ||
| + | if(pin_get_value(S1) == 1) | ||
| + | { | ||
| + | pin_set(led_green); | ||
| + | } | ||
| + | else | ||
| + | { | ||
| + | pin_clear(led_green); | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ==== Filtragem de saltos de interruptor ==== | ||
| + | |||
| + | [{{ : | ||
| + | |||
| + | Principal método usado para evitar cintilação causadas pelo salto de contatos é a filtragem. A filtragem pode ser feita electricamente ou por software. Para filtrar electricamente o interruptor tem de estar ligado através de um filtro passa-baixo - por exemplo, um filtro RC - com alterações de tensão suaves e portanto o pino do microcontrolador não tem valores transitórios. Filtro RC é mostrado no desenho. A filtragem por software é feita através da avaliação do valor do pino quando o interruptor se encontra ligado; se o valor se mantém o mesma um número de vezes em tempo limite pré-definido, | ||
| + | |||
| + | Várias soluções de software são utilizadas para filtrar, isto pode ser realizado de maneiras simples ou complexas com ambas as suas vantagens e desvantagens. Se o programa é configurado para ter apenas algumas mudanças infrequentes do botão, uma longa pausa pode ser configurada para seguir a mudança, esta solução descarta reacção ao salto do interruptor. No entanto, durante a utilização desta solução deve ser considerada - no caso de o utilizador segurar o botão para baixo por um longo período de tempo, o programa reage também na falta de libertação do botão. | ||
| + | |||
| + | Um programa que controla o estado do interruptor várias vezes num período fixo de tempo é mais fiável (quanto mais longo é o tempo e o número de controlos, melhor será o resultado). | ||
| + | |||
| + | ===== Prática ===== | ||
| + | |||
| + | Há três interruptores de botão no módulo de interface de utilizador. Esses interruptores conectam os pinos do microcontrolador à terra, porém não diretamente através de uma resistência, | ||
| + | |||
| + | As posições do interruptor são mostradas na descrição de hardware. A fim de ler o estado dos interruptores, | ||
| + | |||
| + | Abaixo está uma função para leitura de valores filtrados de um botão para o módulo de interface do utilizador: | ||
| + | |||
| + | <code c> | ||
| + | // Function for reading filtered values of a IO extension module | ||
| + | unsigned char button_read(pin button) | ||
| + | { | ||
| + | unsigned char buffer = 0xAA; | ||
| + | unsigned char timeout = 100; | ||
| + | |||
| + | // We wait until the status of the button is celar | ||
| + | // or clearing the state expires | ||
| + | while (timeout-- > 0) | ||
| + | { | ||
| + | // Having 8 place (bit) bufffer of state | ||
| + | // All previous states (bits) are shifted to left | ||
| + | // and a new state(bit) is added to the right | ||
| + | buffer <<= 1; | ||
| + | buffer |= (pin_get_value(button) ? 0x01 : 0x00); | ||
| + | |||
| + | // If all 8 bits are high, then the button is pressed down | ||
| + | if (buffer == 0xFF) | ||
| + | { | ||
| + | return 0; | ||
| + | } | ||
| + | |||
| + | // If all 8 bits are low, then the button is definitely up | ||
| + | if (buffer == 0x00) | ||
| + | { | ||
| + | return 1; | ||
| + | } | ||
| + | |||
| + | // 1 ms break | ||
| + | // This function can be found from the library of the HomeLab | ||
| + | _delay_ms(1); | ||
| + | } | ||
| + | // If can't examine the state, then assume that button was not pressed | ||
| + | return 0; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Esta função gera um atraso usando uma função que é explicado no exercício correspondente. Neste momento, tudo o que precisamos saber sobre a função de atraso é que gera um atraso de 1 ms no final de cada ciclo para a leitura do estado do botão. Se o botão está na mesma posição durante 8 leituras, retorna para a posição contada. No caso de o botão estar instável todo o procedimento pode levar até 100 ms. Esta função está incluída na biblioteca de pinos, por conseguinte, | ||
| + | |||
| + | O exemplo seguinte ilustra o uso de botões e a eliminação de contagem múltipla utilizando um ciclo vazio. O botão é esperado para libertar-se durante um ciclo vazio. | ||
| + | |||
| + | <code c> | ||
| + | // The program for filtering the debounce of buttons of User interface module | ||
| + | #include < | ||
| + | |||
| + | // Main program | ||
| + | int main(void) | ||
| + | { | ||
| + | int counter = 0; | ||
| + | |||
| + | // Set LED pins as output and switch pin as input | ||
| + | pin_setup_output(led_red); | ||
| + | pin_setup_output(led_yellow); | ||
| + | pin_setup_output(led_green); | ||
| + | |||
| + | pin_setup_input(S1); | ||
| + | |||
| + | // Endless loop | ||
| + | while(1) | ||
| + | { | ||
| + | // Check if switch S1 is pressed | ||
| + | if(button_read(S1)) | ||
| + | { | ||
| + | // Light the corresponding LED | ||
| + | if(counter == 0) led_on(led_green); | ||
| + | else led_off(led_green); | ||
| + | if(counter == 1) led_on(led_yellow); | ||
| + | else led_off(led_yellow); | ||
| + | if(counter == 2) led_on(led_red); | ||
| + | else led_off(led_red); | ||
| + | |||
| + | // Add counter and take a module | ||
| + | counter = (counter + 1) % 3; | ||
| + | |||
| + | // Wait until switch is unpressed | ||
| + | while(button_read(S1) != 0); | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Se testamos este programa agora, os LEDs ficam iluminando exatamente nesta sequência enquanto o utilizador pressiona o interruptor. | ||
| + | O exemplo deste código é baseado na biblioteca de pinos do Robotic HomeLab que é introduzido no capítulo [[en: | ||
| + | |||
| + | Na tabela abaixo constam as descrições constantes dos botões e pinos apropriados do módulo controlador. | ||
| + | |||
| + | ^Nome da constante^pino HomeLab I & II^pino HomeLab III^Descrição^ | ||
| + | |S0|PC2|PQ2|Botão de teste no módulo controlador| | ||
| + | |S1|PC0|PH2|Botão baixo no módulo de interface do utilizador| | ||
| + | |S2|PC1|PH1|Botão médio no módulo de interface do utilizador| | ||
| + | |S3|PC2|PH0|Botão alto no módulo de interface do utilizador| | ||
| + | |||
| + | <code c> | ||
| + | // Button demonstration example of User interface module | ||
| + | #include < | ||
| + | |||
| + | // Main program | ||
| + | int main(void) | ||
| + | { | ||
| + | // Set LED pins as output and switch pin as input | ||
| + | pin_setup_output(led_red); | ||
| + | pin_setup_output(led_yellow); | ||
| + | pin_setup_output(led_green); | ||
| + | |||
| + | pin_setup_input(S1); | ||
| + | pin_setup_input(S2); | ||
| + | pin_setup_input(S3); | ||
| + | |||
| + | // Endless loop | ||
| + | while (1) | ||
| + | { | ||
| + | // Every button press lights one LED | ||
| + | if(button_read(S1)) led_on(led_green); | ||
| + | else led_off(led_green); | ||
| + | if(button_read(S2)) led_on(led_yellow); | ||
| + | else led_off(led_yellow); | ||
| + | if(button_read(S3)) led_on(led_red); | ||
| + | else led_off(led_red); | ||
| + | } | ||
| + | } | ||
| + | </ | ||