Pensando nisso, aproveitei que estava com a mão na massa com o meu último artigo sobre Rotary Encoders, e desenvolvi uma classe pra escrever texto em um display LCD através de um Rotary Encoder.
Para maiores detalhes sobre o Rotary Encoder veja o artigo completo aqui: http://fabianoallex.blogspot.com.br/2016/05/arduino-rotary-encoder.html
Vídeo:
Código-Fonte:
/* Fabiano A. Arndt - 2016 www.youtube.com/user/fabianoallex www.facebook.com/dicasarduino fabianoallex@gmail.com */ #include <LiquidCrystal.h> /************************************************************************************************************* ************************************CLASSE ROTARY ENCODER***************************************************** *************************************************************************************************************/ #define ROTARY_NO_BUTTON 255 struct RotaryEncoderLimits{ int min; int max; }; class RotaryEncoder { private: byte _pin_clk; byte _pin_dt; byte _pin_sw; volatile byte _num_results; volatile int _result; volatile int * _results; byte _index_result; RotaryEncoderLimits * _limits; boolean _a; boolean _b; public: RotaryEncoder(byte pin_clk, byte pin_dt, byte pin_sw = ROTARY_NO_BUTTON, byte num_results=1, RotaryEncoderLimits * limits=0){ //parametro do botao opcional _pin_clk = pin_clk; _pin_dt = pin_dt; _pin_sw = pin_sw; pinMode(_pin_clk, INPUT); pinMode(_pin_dt, INPUT); if (_pin_sw != ROTARY_NO_BUTTON){ pinMode(_pin_sw, INPUT); digitalWrite(_pin_sw, HIGH); } if (num_results == 0) { num_results = 1; } _num_results = num_results; _results = new int[_num_results]; for (int i; i<_num_results; i++){ _results[i] = (limits) ? limits[i].min : 0; } _index_result = 0; _limits = limits; _a = false; _b = false; } byte getIndex() { return _index_result; } void next() { _index_result++; if (_index_result >= _num_results) { _index_result = 0; } } void update_a() { _result = 0; delay (1); if( digitalRead(_pin_clk) != _a ) { _a = !_a; if ( _a && !_b ) { _result = -1; } } if (_results[_index_result]+_result >= _limits[_index_result].min && _results[_index_result]+_result <= _limits[_index_result].max ) { _results[_index_result] += _result; } } void update_b() { _result = 0; delay (1); if( digitalRead(_pin_dt) != _b ) { _b = !_b; if ( _b && !_a ) { _result = +1; } } if (_results[_index_result]+_result >= _limits[_index_result].min && _results[_index_result]+_result <= _limits[_index_result].max ) { _results[_index_result] += _result; } } int read(){ return _result; } //retorn -1, 0 ou 1. int getValue(int index=-1) { //retorna o valor da variável corrente ou a passada como parametro if (index < 0 ){ return _results[_index_result]; } return _results[index]; } void setValue(int value) { _results[_index_result] = value; } //caso a variável inicializa em determinado valor diferente de zero, utilizar esse método. void setValue(int index, int value){ _results[index] = value; } //caso a variável inicializa em determinado valor diferente de zero, utilizar esse método. int buttonRead(){ return (_pin_sw == ROTARY_NO_BUTTON) ? LOW : digitalRead(_pin_sw); } }; /************************************************************************************************************* ************************************FIM CLASSE ROTARY ENCODER************************************************* *************************************************************************************************************/ /************************************************************************************************************* ************************************CLASSE ROTARY KEYBOARD**************************************************** *************************************************************************************************************/ const char teclas[] = {"abcdefghijklmnopqrstuvxwyz 0123456789"}; //caracteres a serem escolhidos const unsigned long time_char = 1200; //1200 milissegundos pra desconsiderar a ultima tecla class RotaryKeyBoard { private: unsigned long _millis_last_char; char _last_char; String _palavra; RotaryEncoder * _re; void _set_last_char(char c, int ind_palavra){ if ( ind_palavra == 1 && _last_char != '\0' ) { _palavra += _last_char; } _last_char = c; _millis_last_char = millis(); } void _add(char c) { if ( is_timing() ) { _set_last_char( (teclas[_re->getValue(0)] == '\0') ? _last_char = teclas[0] : _last_char = teclas[_re->getValue(0)] , 0 ); return ; } _set_last_char (c, 1); } public: RotaryKeyBoard(RotaryEncoder * re){ _re = re; _millis_last_char = millis(); _last_char = '\0'; _palavra = ""; update(); backspace(); _re->setValue(0, 0); } char get_last_char() { return _last_char; } int is_timing() { return ( (millis() - time_char) < _millis_last_char ); } String get_palavra() { return (_last_char) ? _palavra + _last_char : _palavra; } void backspace(){ if (_palavra.length() >= 1){ _last_char = _palavra[_palavra.length()-1]; _palavra = _palavra.substring(0, _palavra.length()-1); } else { _last_char = '\0'; } } void update() { static char tecla_anterior = '\0'; char tecla = teclas[_re->getValue(0)]; if (tecla != tecla_anterior){ if (tecla) { _add(tecla); } } tecla_anterior = tecla; } }; /************************************************************************************************************* ************************************FIM CLASSE ROTARY KEYBOARD************************************************ *************************************************************************************************************/ /************************************************************************************************************* ************************************DECLARACOES DOS OBJETOS*************************************************** *************************************************************************************************************/ LiquidCrystal lcd(12, 11, 10, 9, 8, 7); RotaryEncoderLimits lim[] = { {0, sizeof(teclas)-1 } }; //limites máximos e mínimos que as variaveis podem atingir RotaryEncoder re(A0, A1, 4, 1, lim); //pino clk, pino dt, pino sw, variaveis RotaryKeyBoard teclado(&re); /************************************************************************************************************* ************************************FIM DECLARACOES DOS OBJETOS*********************************************** *************************************************************************************************************/ /************************************************************************************************************* ************************************TRATAMENTO DAS INTERRUPÇÕES*********************************************** *************************************************************************************************************/ ISR(PCINT1_vect) { volatile static byte lastVal_a0 = LOW; volatile static byte lastVal_a1 = LOW; byte val_a0 = digitalRead(A0); byte val_a1 = digitalRead(A1); if (lastVal_a0 != val_a0){ re.update_a(); lastVal_a0 = val_a0; } if (lastVal_a1 != val_a1){ re.update_b(); lastVal_a1 = val_a1; } } void setup_interrupts(){ pinMode(A0,INPUT); // set Pin as Input (default) digitalWrite(A0,HIGH); // enable pullup resistor pinMode(A1,INPUT); // set Pin as Input (default) digitalWrite(A1,HIGH); // enable pullup resistor cli(); PCICR |= 0b00000010; // habilita a porta C - Pin Change Interrupts PCMSK1 |= 0b00000011; // habilita interrupção da porta c nos pinos: PCINT8 (A0) e PCINT9(A1) sei(); } /************************************************************************************************************* ************************************FIM TRATAMENTO DAS INTERRUPÇÕES******************************************* *************************************************************************************************************/ /************************************************************************************************************* ************************************SETUP / LOOP************************************************************** *************************************************************************************************************/ void setup() { setup_interrupts(); lcd.begin(16, 2); Serial.begin(9600); } void loop() { teclado.update(); lcd.clear(); lcd.setCursor(0, 0); lcd.print(teclado.get_palavra()); lcd.cursor(); lcd.setCursor(teclado.get_palavra().length() - (teclado.is_timing() ? 1 : 0 ), 0); //controla o click do botao do enconder static byte b = HIGH; //pra ler apenas uma vez o botao ao pressionar if( re.buttonRead() == LOW && b != re.buttonRead() ) { teclado.backspace(); delay(200); } b = re.buttonRead(); delay(100); } /************************************************************************************************************* ************************************FIM SETUP / LOOP************************************************************** *************************************************************************************************************/
keep getting error in compiling
ResponderExcluirstray'(\302)' in program
help
In English
ExcluirThis error can happen when you copy the code from some website and something comes along, some html instruction for example.
Copy the code and paste it into some notepad, then copy it again from the notepad and then paste it into the Arduino ide. This will make the code clean for the Arduino.
Em Portugues
Esse erro pode acontecer quando você copia o codigo de algum site e vem alguma coisa junto, alguma instrução de html por exemplo.
Copie o codigo e cole em algum bloco de notas, depois copie novamente do bloco de notas e dai cole na ide do arduino. Isso fara que o codigo va limpo para o arduino.