viernes, 12 de febrero de 2016

Arduino UNO - Rotary Encoder

Arduino UNO - Rotary Encoder

Exemple 1: Fa una sortida per el port serial
/* Read Quadrature Encoder
  * Connect Encoder to Pins encoder0PinA, encoder0PinB, and +5V.
  *
  * Sketch by max wolf / www.meso.net
  * v. 0.1 - very basic functions - mw 20061220
  *
  */ 

 int val;
 int encoder0PinA = 11;
 int encoder0PinB = 12;
 int encoder0Pos = 0;
 int encoder0PinALast = LOW;
 int n = LOW;

 void setup() {
   pinMode (encoder0PinA,INPUT);
   pinMode (encoder0PinB,INPUT);
   Serial.begin (9600);
 }

 void loop() {
   n = digitalRead(encoder0PinA);
   if ((encoder0PinALast == LOW) && (n == HIGH)) {
     if (digitalRead(encoder0PinB) == LOW) {
       encoder0Pos--;
     } else {
       encoder0Pos++;
     }
     Serial.print (encoder0Pos);
     Serial.println ("/");
   }
   encoder0PinALast = n;
 }

Exemple 2: Variació de la brillantor de un led (PWM)
/*
** Rotary Encoder Example
** Use the Sparkfun Rotary Encoder to vary brightness of LED
**
** Sample the encoder at 200Hz using the millis() function
*/

int brightness = 120;    // how bright the LED is, start at half brightness
int fadeAmount = 10;    // how many points to fade the LED by
unsigned long currentTime;
unsigned long loopTime;
const int pin_A = 12;  // pin 12
const int pin_B = 11;  // pin 11
unsigned char encoder_A;
unsigned char encoder_B;
unsigned char encoder_A_prev=0;

void setup()  {
  // declare pin 9 to be an output:
  pinMode(9, OUTPUT);
  pinMode(pin_A, INPUT);
  pinMode(pin_B, INPUT);
  currentTime = millis();
  loopTime = currentTime;
}

void loop()  {
  // get the current elapsed time
  currentTime = millis();
  if(currentTime >= (loopTime + 5)){
    // 5ms since last check of encoder = 200Hz 
    encoder_A = digitalRead(pin_A);    // Read encoder pins
    encoder_B = digitalRead(pin_B);  
    if((!encoder_A) && (encoder_A_prev)){
      // A has gone from high to low
      if(encoder_B) {
        // B is high so clockwise
        // increase the brightness, dont go over 255
        if(brightness + fadeAmount <= 255) brightness += fadeAmount;               
      }  
      else {
        // B is low so counter-clockwise     
        // decrease the brightness, dont go below 0
        if(brightness - fadeAmount >= 0) brightness -= fadeAmount;              
      }  

    }  
    encoder_A_prev = encoder_A;     // Store value of A for next time   
   
    // set the brightness of pin 9:
    analogWrite(9, brightness);  
  
    loopTime = currentTime;  // Updates loopTime
  }
  // Other processing can be done here
                          
}

Display LCD via I2C - 18F4550 - 18F2550

Gobierno de un display LCD via I2C 

18F4550 - 18F2550 - CCS Compiler

– Ejemplo para un PIC:

El esquema de montaje es el siguiente :
esquema_pic_i2c
– Ejemplo para un PIC:
El esquema de montaje es el siguiente (pulsa botón derecho “ver imagen” para ampliarla):
/*
#include <16F88.h>                        //pic a utilizar
#fuses NOWDT,NOPROTECT,PUT,NOLVP, NOMCLR,INTRC_IO, NODEBUG  
#use delay (clock=8000000)                  //Fosc=8Mhz
#use standard_io(A)
#use standard_io(B)
#use i2c(Master,Fast=100000, sda=PIN_B1, scl=PIN_B4,force_sw)
#include <i2c_Flex_LCD.h>                //libreria manejo lcd
/**/
#include <18f4550.h>
#device ICD = TRUE
#device ADC=10
#use delay (clock=48000000)
//#use i2c(Master,Fast=100000, sda=PIN_D6, scl=PIN_D7,force_sw)
#use i2c(Master,Fast=100000, sda=PIN_B0, scl=PIN_B1,force_sw)
#include <i2c_Flex_LCD.h>
#fuses HSPLL,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,USBDIV,PLL5,CPUDIV1,DEBUG // configura fuses
/**/
void main()
{
//Char="Test";
int16 test=1;

  lcd_init();
  i2c_lcd_backlight_On();

   while(TRUE)
   {
         test=test+1;
        
         lcd_clear();  //Clear Display
         printf(LCD_PUTC,"\1%s","LCD Line 1");  //Print on LCD line 1
         delay_ms(2000);

         printf(LCD_PUTC,"\2%s","LCD Line 2");  //Print on LCD line 2
         delay_ms(2000);
      
         printf(LCD_PUTC,"\f\1%s","LCD Line 1");
  //Clear display, print again on Line 1
         delay_ms(2000);
        
         printf(LCD_PUTC,"\f\2%s","LCD Line 2");
  //Clear display, print again on Line 2
         delay_ms(2000);
        
         i2c_lcd_backlight_Off();
         printf(LCD_PUTC,"\f\1%s\2%s","LCD BackLight","     OFF      "); //Clear display, print again on Line 1
         delay_ms(2000);
        
         i2c_lcd_backlight_On();
         printf(LCD_PUTC,"\f\1%s\2%s","LCD BackLight","     ON      "); //Clear display, print again on Line 2
         delay_ms(2000);
        
         //Al estilo tradicional:
         lcd_clear();
         lcd_gotoxy(1,1);
         printf(LCD_PUTC,"Linea 1 - Tradicional");
         delay_ms(2000);
         lcd_gotoxy(1,2);
         printf(LCD_PUTC,"Linea 2 - Tradicional");
         delay_ms(2000);
   }  
}


El ejemplo está programado con el compilador CCS, se hace necesaria una librería para gobernar el modulito, esta es la llamada “i2c_Flex_LCD.h” creada por el autor: Hugo Silva. se puede descargar junto con el ejemplo de aquí: lcd_i2c.
La librería nos da funciones para escribir en la pantalla LCD de varias formas, una es del modo tradicional con goto_xy:
         lcd_gotoxy(1,1);
         printf(LCD_PUTC,”Linea 1″);
primero nos posicionamos en la coordenada deseada, y luego se escribe a partir de ahí. La otra forma es especificando la línea dentro de las comillas “1”:
         printf(LCD_PUTC,”1%s”,”LCD Line 1″);
También dispone de otras funciones para encender y apagar la luz del display de fondo:
          i2c_lcd_backlight_On();
          i2c_lcd_backlight_Off();
 así como para borrar el display:
           lcd_clear();
-Dirección del bus I2C:
Una cosa muy importante a tener en cuenta es la dirección del bus I2C, en este modulo, se pueden usar ocho diferentes según esta tablita:
Las direcciones en caso del PIC son las siguientes:
Jp3 Jp2 Jp1
A2 A1 A0  Hex
L L L  0x40
L L H  0x42
L H L  0x44
L H H  0x46
H L L  0x48
H L H  0x4A
H H L  0x4C
H H H  0x4E
Y se especifican en la librería en la línea:
    #define LCD_ADDR       0x4E //I2C slave address for LCD module
Descargas: lcd_i2c.

miércoles, 10 de febrero de 2016

Pin Change Interrupt

/*
Copyright 2011 Lex.V.Talionis at gmail
This program is free software:
*/
#include <PinChangeInt.h>
#include <PinChangeIntConfig.h>

#define PIN 15  // the pin we are interested in
volatile byte burp=0;    // a counter to see how many times the pin has changed
byte cmd=0;     // a place to put our serial data

void setup() {
    Serial.begin(9600);
    Serial.print("PinChangeInt test on pin ");
    Serial.print(PIN);
    Serial.println();
    pinMode(PIN, INPUT);     //set the pin to input
    digitalWrite(PIN, HIGH); //use the internal pullup resistor
    PCintPort::attachInterrupt(PIN, burpcount,RISING);
    // attach a PinChange Interrupt to our pin on the rising edge
    // (RISING, FALLING and CHANGE all work with this library)
    // and execute the function burpcount when that pin changes
}

void loop() {
  cmd=Serial.read(); 
  if (cmd=='p')
  {
    Serial.print("burpcount:\t");
    Serial.println(burp, DEC);
  }
  cmd=0;
}

void burpcount()
{
  burp++;
}