miércoles, 24 de febrero de 2016

ChibiOS para el IDE Arduino

Un sistema operativo en tiempo real es una pieza bastante complicado de software, incluso con una pequeña RTOS - debido a la forma en que se mete con varios detalles de bajo nivel de ejecución del código, tales como pilas y las interrupciones. Es por lo tanto no es poca cosa cuando todo se puede hacer como una biblioteca de complemento estándar para el IDE de Arduino.
Pero eso es exactamente lo que ha sido hecho por Bill Greiman con ChibiOS , en forma de una biblioteca llamada "ChibiOS_AVR" (también hay una versión ARM para la debida y Teensy).
Así que vamos a continuar donde lo dejé ayer e instalar esta cosa para su uso con JeeNodes, eh?
  • descargar una copia de ChibiOS20130208.zip de esta página en Google Code
  • descomprimirá y el interior encontrará una carpeta llamada ChibiOS_AVR
  • moverlo dentro de la bibliotecas carpeta en su carpeta de bocetos IDE (al lado de JeeLib, etc)
  • También puede ser que desee mover ChibiOS_ARM y SdFat junto a él, para su uso posterior
  • otras cosas en ese archivo ZIP son un archivo README y la documentación HTML
  • eso es todo, ahora relanzar el IDE de Arduino para que sea reconocer las nuevas bibliotecas
Eso es realmente todo lo que hay que hacer. La carpeta ChibiOS_AVR también contiene una docena de ejemplos, cada uno de los cuales es digno de mirar en y probar. Tenga en cuenta que no hay ningún LED en un JeeNode estándar, y que el LED azul del USB JeeNode SMD y JeeNode está en el pin 9 y tiene una polaridad inversa ( "0" a su vez en "1" apagarlo ).
Nota: Estoy usando esto con Arduino IDE 1.5.2, pero también debería funcionar con 1.0.x IDE
Las cosas simples son todavía relativamente simple con un RTOS, pero estar preparados para hacer frente a toda una serie de nuevos conceptos y técnicas cuando realmente comienza a sumergirse en un montón de maneras de hacer las tareas e interrumpe el trabajo en conjunto -. Exclusiones mutuas, semáforos, eventos, colas, buzones ...
Por suerte, ChibiOS viene con una gran cantidad de documentación, incluyendo algunos generales guías y de cómo-a . La documentación AVR-específica se puede encontrar aquí(al igual que en ese archivo ZIP que acaba de descargar).
No estoy seguro de que este es el mejor lugar para ello, pero he puesto el ejemplo de ayer en JeeLib por ahora.
Me gustaría ir a la RTOS y ChibiOS un poco más en las próximas semanas, aunque sólo sea para ver cómo la comunicación inalámbrica y los modos de suspensión de baja potencia se pueden montar en ese país.
Solo un dato por ahora: la latencia de cambio de contexto de ChibiOS en una ATmega328 @ 16 MHz parece ser alrededor de 15 mu s. O, para decirlo de otra manera: se puede cambiar entre múltiples tareas durante sesenta mil veces por segundo. Trago.
TUTORIAL

1 El muestreo usando el ADC

Fig.1 - Potenciómetro diagrama.
Un análogo al convertidor digital de es un dispositivo que convierte una cantidad física continua (por lo general de tensión) a un número digital que representa la amplitud de la cantidad.
En esta demostración, estamos muestreando voltaje a través de unpotenciómetro para establecer su posición. Un potenciómetro es un mando de tres pines que proporciona una resistencia variable entre WA y WB pasadores (Fig.1). Cantidad de resistencia entre A y B es constante, pero girando el eje del potenciómetro, cambiamos la cantidad de resistencia a cada lado de W.
Conexión de A a 3 V, B a GND (o viceversa) y la tensión de muestreo entre W y GND que podría medir la posición del limpiaparabrisas: según divisor de voltaje , el voltaje muestreado sería proporcional a la cantidad de resistencia entre W y el pasador conectado a GND.

2 ADC en ChibiOS

STM32 tiene más de un ADC. Como siempre, tuvimos que permitirá subsistema ADC en halconf.h y controlador adecuado en mcuconf.h .
Cada ADC tiene más de un canal. Podríamos tomar muestras de estos canales que eligen una secuencia personalizada. Con el fin de hacer que teníamos que configurar algún registro ADC aunqueADCConversionGroup . Por otra parte, podríamos configurar la frecuencia de muestreo y el modo. Nuestro grupo de conversión es:
/ *
 * Grupo de conversión ADC.
 * Modo: tampón circular, 10 muestras de 1 canal, SW activa.
 * Canales: IN0.
 * / 
Static  const ADCConversionGroup my_conversion_group = {
  FALSO,                             / * NO CIRCULAR * / 
  MY_NUM_CH,                         / * NUMB DE CH * / 
  NULL ,                              / * NO ADC RETROLLAMADA * / 
  NULL ,                              / * NO ADC ERROR RETROLLAMADA * / 
  0 ,                                 / * CR1 * / 
  ADC_CR2_SWSTART,                   / * CR2 * / 
  0 ,                                 / * * SMPR1 / 
  ADC_SMPR2_SMP_AN0 (ADC_SAMPLE_3),   / * * SMPR2 / 
  ADC_SQR1_NUM_CH (MY_NUM_CH),        / * SQR1 * / 
  0 ,                                 / * * SQR2 / 
  ADC_SQR3_SQ1_N (ADC_CHANNEL_IN0)    / * SQR3 * / 
};
Estamos muestreando de forma no circular, de un solo canal ( ADC_CHANNEL_IN0 ). La frecuencia de muestreo es igual a tres ciclos de reloj principal ( ADC_SAMPLE_3 ), (Para más información ver para los registros de ADC en Manual de referencia).
Hemos desactivado el dos de devolución de llamada de ADC. La primera de ellas se produce durante el muestreo dos veces (en el medio y en el final del grupo de conversión); el segundo se produce en caso de error ADC.
En principal tuvimos para configurar nuestra pasador. En hilo de ADC que empezamos, el muestreo de un tampón de n elementos y hacer que significa en los datos con el fin de eliminar el ruido.
estática msg_t Thd2 ( void * arg)  {
   unsigned II;
  ( Vacío ) arg;
  chRegSetThreadName ( "controlador Led" );
   / *
   * Activa el conductor ADC1.
   * / 
  AdcStart (y ADCD1, NULL );
   mientras que (TRUE) {
    adcConvert (y ADCD1, y my_conversion_group, sample_buff, MY_SAMPLING_NUMBER); . / * Hacer media de los valores muestreados * / 
    media = 0 ;
     para (ii = 0 ; ii <MY_NUM_CH * MY_SAMPLING_NUMBER; ii ++) {
    
      media + = sample_buff [ii];
    }
    decir / = MY_NUM_CH * MY_SAMPLING_NUMBER;
    lastvalue = ( float ) significa * 3 / 4096 ;
    flag = true;
  }
  volver  0 ;
}
Tenga en cuenta que podemos utilizar el ADC en modo continuo utilizando otro API: adcStartConversion () .Recuerde siempre que teníamos a la dimensión muestras de tampón correctamente para evitar un desbordamiento:
estática  adcsample_t sample_buff [MY_NUM_CH * MY_SAMPLING_NUMBER];

3 de atenuación mediante PWM

La figura 2 -Relation entre el ciclo de trabajo y el valor medio.
La modulación por ancho de pulso es una técnica utilizada para codificar un mensaje en una señal pulsante. Es un tipo de modulación. Aunque esta técnica de modulación puede utilizarse para codificar la información para su transmisión, su uso principal es permitir el control de la potencia suministrada a los aparatos eléctricos, especialmente a las cargas inerciales tales como motores.
Por otra parte, podemos usar PWM a desvanecerse la intensidad del LED.Esto es posible gracias principio de que el valor medio de PWM es proporcional a su ciclo de trabajo .

4 PWM en ChibiOS

Simplificando, PWM es una onda cuadrada que se caracteriza por un período fijo y un ciclo de trabajo variable.La mejor manera de darse cuenta de que está utilizando un contador de tiempo. La fijación de la frecuencia del temporizador, (de ahí período), podríamos definir periodo PWM y ciclo de trabajo como múltiplo del temporizador cuántica. Tenga en cuenta que la frecuencia del temporizador debe ser varios órdenes de magnitud mayor que la frecuencia de PWM con el fin de tener una buena resolución ciclo de trabajo.
En este punto, debe quedar claro que la frecuencia del campo de PWMConfig se denomina temporizador relacionado y que hay un temporizador para cada PWM. . Dado que cada temporizador como algo más que un canal que podría generar más de PWM con el mismo periodo pero diferente ciclo de trabajo
del controlador PWM tiene devoluciones de llamada: una es común a cada canal y se produce cada periodo, otros son de canal en función y se producen cuando los interruptores de salida PWM, por lo tanto, depende de ciclo de trabajo. Esta es la PWMConfig verde usado desvaneciendo LED de intensidad:
estática PWMConfig pwmcfg = {
   1000000 ,                                     / * 1 MHz de frecuencia de reloj PWM. * / 
  1000 ,                                        / * Período Inicial de PWM de 1 ms. * /
  pwmpcb,
  {
   {PWM_OUTPUT_ACTIVE_HIGH, pwmc1cb},
   {PWM_OUTPUT_DISABLED, NULL },
   {PWM_OUTPUT_DISABLED, NULL },
   {PWM_OUTPUT_DISABLED, NULL }
  },
  0 ,
   0 
};

Tenga en cuenta que la frecuencia del temporizador es de 1 MHz y que PWM periodo inicial es de 1000 es decir temporizador cuántica 1ms. Pwmpcb es el período de devolución de llamada y pwmc1cb es la devolución de llamada del canal 1; Por otra parte, el primer canal está activo y la salida es alta durante un período de tiempo proporcional al ciclo de trabajo, en lugar de otros canales están desactivados.
Como todos los pilotos, PWM debe iniciarse antes de usarlo. PWM API permite iniciar la elección de los canales de ciclo de trabajo, así como el período de PWM cambio, canal desactivado y dejar de conducir. Con el fin de LED se desvanecen apenas comenzamos el conductor antes de lazo de hilo y permitir que continuamente cambiando de canal ciclo de trabajo (en nuestro caso elegimos el ciclo de trabajo proporcional a durar valor muestreado).
estática msg_t Thd1  ( void * arg)  { 
  ( vacío ) arg;
  chRegSetThreadName ( "controlador Led" );
  pwmStart (y PWMD1, y pwmcfg); mientras que (TRUE) {
  
    porcentaje = lastvalue * 10.000 / 3 ;
     si (porcentaje < 100 ) {
      porcentaje = 0 ;
      pwmDisableChannel (y PWMD1, 0 );
      palClearPad (GPIOA, GPIOA_LED_GREEN);
    }
    otra cosa  si (porcentaje> 9900 ) {
      porcentaje = 10000 ;
      pwmDisableChannel (y PWMD1, 0 );
      palSetPad (GPIOA, GPIOA_LED_GREEN);
    }
    otra cosa {
      pwmEnableChannel (y PWMD1, 0 , PWM_PERCENTAGE_TO_WIDTH (y PWMD1, porcentaje));
    }
    chThdSleepMilliseconds ( 1 );
  }
  volver RDY_OK;
}

LED verde no está conectado directamente a nuestra salida del temporizador y utilizamos las devoluciones de llamada para hacer una PWM de software. Cuando el ciclo de trabajo es del 0% o 100% entre uno pwmpcb ypwmc1cb devoluciones de llamada no podría ocurrir: que explica los controles sobre los bordes del ciclo de trabajo.
estática  vacío  pwmpcb (PWMDriver * pwmp)  { 
  ( vacío ) pwmp;
   si (porcentaje)
    palSetPad (GPIOA, GPIOA_LED_GREEN);
} Static void pwmc1cb (PWMDriver * pwmp) {   ( vacío ) pwmp;
   

  palClearPad (GPIOA, GPIOA_LED_GREEN);
}
Recuerde que antes de usar PWM para permitir subsistema en halconf.h y asignar temporizador en mcuconf.h.

5 La rueda de color

La conducción de un LED RGB utilizamos tres canales de la misma PWM. Rueda de colores evitar que más de dos uniones se afinan juntos: esto porque encender el tercer cambio de color de unión hacia la saturación perdedora blanco.
mientras que (TRUE) {
  tmp = lastvalue * 90 ;
  ii = tmp / 90 ;
  jj = tmp% 90 ;
   si (== ii 0 ) {
    porcentaje [ 0 ] = 10.000 * sin (jj * 3,14 / 180 );
    porcentaje [ 1 ] = 0 ;
    porcentaje [ 2 ] = 10.000 * cos (jj * 3,14 / 180 );
  }
  otra cosa  si (ii == 1 ) {
    porcentaje [ 0 ] = 10.000 * cos (jj * 3,14 / 180 );
    porcentaje [ 1 ] = 10.000 * sin (jj * 3,14 / 180 );
    porcentaje [ 2 ] = 0 ;
  }
  otra cosa  si (ii == 2 ) {
    porcentaje [ 0 ] = 0 ;
    porcentaje [ 1 ] = 10.000 * cos (jj * 3,14 / 180 );
    porcentaje [ 2 ] = 10.000 * sin (jj * 3,14 / 180 ); 
  ...
  
}

6 Nuestro circuito

El circuito que hicimos para conducir el LED RGB es la siguiente:
Fig.3 - El muestreo y el circuito de regulación de luz.

7 Proyecto utilizado en este tutorial

Este código ha sido probado utilizando ChibiOS / RT 3.0.x.

No hay comentarios:

Publicar un comentario