Control de un display de 7 segmentos con Netduino+


 Netduino es una plataforma de desarrollo de código abierto integrado similar a la famosa plataforma  Arduino, excepto que utiliza .NET Micro Framework para su programación.  La placa de desarrollo Netduino tiene el mismo factor que Arduino Uno, y por lo tanto la mayoría de los escudos de Arduino son también compatibles con Netduino.  Las placas de desarrollo Arduino se basan en 8 bits microcontroladores Atmel que corren a una velocidad máxima de reloj de 16 MHz en su versión primera ,pero  el hardware Netduino usa potentes procesadores de 32 bits (en el caso de la primera versión un  Atmel SAM7x en Netduino, y STMicro STM32F4 en versiones Netduino Plus) y funciona a una velocidad mucho más rápida (48 MHz a 168 MHz).

En el  siguiente ejemplo  extraido de  embedded-lab.com  ademas de intenatr  dar  una  introducción a la plataforma Netduino  y asegurar que cualquier principiante, estudiante o aficionado, será rápidamente capaz de empezar a usarlo para sus propios proyectos y diseños embebidos vamos   a ver la  gestiona de un display  de 7 segmentos de  led   con nuestro Netduino Plus .

Netduino-Plus  como webserver interactuando con dispositivos

Una salida visual siempre añade valor a cualquier proyecto .En esta  ocasión , vamos a mostrar un poco de información numérica, alfabética, así como dos personajes simbólicos en un módulo LED de siete segmentos de 4 dígitos en función de luminosidad captada por una foto-resistencia,es decir vamos a  leer una tensión analógica de un sensor LDR y mostraremos la salida del ADC en cuatro  módulos de siete segmentos.

En realidad el control de un display de 7 segmentos ( en realidad 8 si contamos con el punto) , es bastante intuitivo  , si  se piensa en que cada segmento  corresponde a un solo led .Por ejemplo para mostrar dígito «1», tenemos que enviar la señal de alto para el LED «b» y «c» solamente y tierra el cátodo.

Como un display cuenta con siete segmentos LED se hace con siete más un LED, cada LED tiene su propio nombre, por ejemplo ,si   tenemos que mostrar «15» la forma en que hacemos es mostrando un  «1» ( segmentos B y C) en un bloque LED ,luego  apagamos ese primer display ( cátodo a uno lógico)    y luego nos vamos a mostrar «5» en el segundo display LED( segmentos A,F,G y D)   y luego  lo apagamos también (cátodo a uno lógico),  y repetimos el bucle indefinidamente :esto es  básicamente  la multiplexación porque todos lo segmentos los unimos eléctricamente para ahorrar bits de control  de modo que solo controlamos el encendido de uno de ellos a una frecuencia tan rápida que sea inapreciable por el ojo humano

.

15.png

 

Configuración de Circuito y Teoría

En la sección analógica, hemos utilizado una LDR como nuestro dispositivo de entrada analógica. Con la iluminación, la resistencia de la LDR cambiará causando el cambio en el voltaje  debido al divisor de tensión formado por el LDR y  una resistencia de 10k .La caída o subida de tensión entre el punto de unión entre el  LDR  y la resistencia nos dará  una tensión que conectemos a  nuestro pin analógico A1 de  Netduino

En la sección digital, las conexiones son  también muy  sencillas. Cada pin (a hasta g) de los siete segmentos LED están conectados a los pines digitales DO a D6  de  Netduino+ través de una resistencia de 330 ohmios . Posteriormente cada display de siete segmentos LED al ser estos de  cátodo común y haber cuatro unidades , los controlaremos por  medio de 4  transistores NPN ( por ejemplo BC547)  con  sus resistencias de base de 10k  que conectaremos a los pines digitales D8,D9;D10 y D11 de nuestro Netduino

Cuando la base del transistor está forzado a un uno lógico, el  transistor conduce y  entonces el ánodo correspondiente se conecta a tierra, que completaría  el circuito justo en los segmentos cuyos pines lógicos estén a uno logico encendiendo así  el LED correspondiente a ese led

.
displayleds

 

Programa en c#

El  código escrito por  embedded-lab va usar una  pequeña biblioteca (Clase SevenSegments) que soporta un poco más que los dígitos que muestran. Veamos paso a paso. En el código de abajo, primero creamos una instancia de la clase AnalogInput lo que nos permite obtener el valor de nuestro dispositivo analógico que es LDR en este caso. Luego creamos una instancia independiente de la clase SevenSegments. El constructor de esta clase lleva varios pines como argumentos. Una vez que tenemos SevenSetments instancia simplemente llamar al método Show y pasar el valor que se lee desde el dispositivo analógico

public static void Main()
{AnalogInput aInPin = new AnalogInput(Pins.GPIO_PIN_A1);

//se puede usar cualquier pin analógico

aInPin.SetRange(0, 1234); //dar un rango.
 Debug.Print(«Analog value: » + aInPin.Read());
 // inicializacion del display de 7 segmentos pasando los pines adecuados
SevenSegments sevenSegments = new SevenSegments(
Pins.GPIO_PIN_D0, Pins.GPIO_PIN_D1, Pins.GPIO_PIN_D2,
Pins.GPIO_PIN_D3, Pins.GPIO_PIN_D4, Pins.GPIO_PIN_D5, Pins.GPIO_PIN_D6,
new Cpu.Pin[] { Pins.GPIO_PIN_D8, Pins.GPIO_PIN_D9, Pins.GPIO_PIN_D10, Pins.GPIO_PIN_D11 });

// Valor de pantalla leido por en entrada analogica
sevenSegments.FlickerDelay = 5;
 // Pausa entra cada letra durante la repeticio en una unidd de LED
sevenSegments.UnitSevenSegmentLedDelay = 1;
 //Duracion de una unida led estando a ON
sevenSegments.UnitRepetition = 50;
/// Repeticion de todo la tira
while (true)
{
sevenSegments.Show(aInPin.Read());
Debug.Print(aInPin.Read().ToString());
}
}

El   proceso  pesados ​​principal se hace en la clase SevenSegment. Por lo tanto, vamos a echar un vistazo rápido a las diferentes secciones de esta clase.

Sección constructor de la clase SevenSegment

Aquí hemos definido algunas E / S digitales para los segmentos de LED a hasta g. Para soportar cualquier número de unidades LED, los pines asociados  a ánodos o al cátodo común son recibidos como una matriz. Ahora, para mostrar una carta o un alfabeto, se ha  construido una serie de Boole. Todas estas matrices se almacenan en una tabla hash con una clave que corresponde a un dígito o un alfabeto o un símbolo. Finalmente algunas propiedades se inicializan con algunos valores

 

public SevenSegments(Cpu.Pin a, Cpu.Pin b, Cpu.Pin c, Cpu.Pin d, Cpu.Pin e, Cpu.Pin f,
Cpu.Pin g, Cpu.Pin[] commonAnodeCathodePin)
{
     OutputPort PinD0Out_a = new OutputPort(a, false);
    OutputPort PinD1Out_b = new OutputPort(b, false);
    OutputPort PinD2Out_c = new OutputPort(c, false);
    OutputPort PinD3Out_d = new OutputPort(d, false);
    OutputPort PinD4Out_e = new OutputPort(e, false);
    OutputPort PinD5Out_f = new OutputPort(f, false);
    OutputPort PinD6Out_g = new OutputPort(g, false);
     segmentPins = new OutputPort[] { PinD0Out_a, PinD1Out_b, PinD2Out_c, PinD3Out_d,
PinD4Out_e, PinD5Out_f, PinD6Out_g };
 
    // inicializacion de commonAnodeCathodePin
    ledSegmentUnit = new OutputPort[commonAnodeCathodePin.Length];
    for (int i = 0; i < commonAnodeCathodePin.Length; i++)
    {
        ledSegmentUnit[i] = new OutputPort(commonAnodeCathodePin[i], false);
    }
 
    // crear una lista de caracteres soportados
    ledSegmentTable = new Hashtable();
    ledSegmentTable.Add(«0», new bool[] { true, true, true, true, true, true, false });
    ledSegmentTable.Add(«1», new bool[] { false, true, true, false, false, false, false });
    ledSegmentTable.Add(«2», new bool[] { true, true, false, true, true, false, true });
    ledSegmentTable.Add(«3», new bool[] { true, true, true, true, false, false, true });
    ledSegmentTable.Add(«4», new bool[] { false, true, true, false, false, true, true });
    ledSegmentTable.Add(«5», new bool[] { true, false, true, true, false, true, true });
    ledSegmentTable.Add(«6», new bool[] { true, false, true, true, true, true, true });
    ledSegmentTable.Add(«7», new bool[] { true, true, true, false, false, false, false });
    ledSegmentTable.Add(«8», new bool[] { true, true, true, true, true, true, true });
    ledSegmentTable.Add(«9», new bool[] { true, true, true, true, false, true, true });
    ledSegmentTable.Add(«a», new bool[] { true, true, true, false, true, true, true });
    ledSegmentTable.Add(«b», new bool[] { false, false, true, true, true, true, true });
    ledSegmentTable.Add(«c», new bool[] { true, false, false, true, true, true, false });
    ledSegmentTable.Add(«d», new bool[] { false, true, true, true, true, false, true });
    ledSegmentTable.Add(«e», new bool[] { true, false, false, true, true, true, true });
    ledSegmentTable.Add(«f», new bool[] { true, false, false, false, true, true, true });
    ledSegmentTable.Add(«g», new bool[] { true, true, true, true, false, true, true }); ;
    ledSegmentTable.Add(«h», new bool[] { false, false, true, false, true, true, true });
    ledSegmentTable.Add(«i», new bool[] { false, true, true, false, false, false, false });
    ledSegmentTable.Add(«j», new bool[] { false, true, true, true, true, false, false });
    ledSegmentTable.Add(«l», new bool[] { false, false, false, true, true, true, false });
    ledSegmentTable.Add(«n», new bool[] { false, false, true, false, true, false, true });
    ledSegmentTable.Add(«o», new bool[] { false, false, true, true, true, false, true });
    ledSegmentTable.Add(«p», new bool[] { true, true, false, false, true, true, true });
    ledSegmentTable.Add(«q», new bool[] { true, true, true, false, false, true, true });
    ledSegmentTable.Add(«r», new bool[] { false, false, false, false, true, false, true });
    ledSegmentTable.Add(«s», new bool[] { true, false, true, true, false, true, true });
    ledSegmentTable.Add(«t», new bool[] { false, false, false, true, true, true, true });
    ledSegmentTable.Add(«u», new bool[] { false, false, true, true, true, false, false });
    ledSegmentTable.Add(«y», new bool[] { false, true, true, false, false, true, true });
    ledSegmentTable.Add(«-«, new bool[] { false, false, false, false, false, false, true });
    ledSegmentTable.Add(«?», new bool[] { false, true, true, false, true, true, false });
    ledSegmentTable.Add(«?», new bool[] { true, false, false, true, false, false, true });
 
    // Inicializar campos por defecto
    FlickerDelay = 5;
    SevenSegmentsUnits = commonAnodeCathodePin.Length;
    UnitSevenSegmentLedDelay = 0;
    UnitRepetition = 50;
    RightToLeft = true;
}

Para mostrar un dígito o un signo del alfabeto, vemos  un método Show de esta clase. Hay tres sobrecargas de este método Show  que vamos a ver a continuación.

 

El primero toma int como argumento y llama directamente segundo método Mostrar que tiene cadena como argumento. En este método, dependiendo de si RightToLeft se establece en verdadero o falso, y el código salta a la sección correspondiente. Esta sección básicamente extrae la letra correcta para mostrar y luego llama el tercer método Mostrar.

public void Show(string stringToShow)
{

// este bucle hará que parezca que todos los leds permanezcan encendidos
for (int j = 0; j < UnitRepetition; j++)
{   if (RightToLeft)
{ int ledUnit = SevenSegmentsUnits – 1; // indice basados en 0 index   for (int i = stringToShow.Length; i > 0; i–)
{
string eachLetter = stringToShow.Substring(i – 1, 1);
Show(eachLetter, ledUnit);
ledUnit -= 1;
 
// si longitud de stringToShowes mayor que
// SevenSegmentsUnits los restamos
if (ledUnit < 0) ledUnit = SevenSegmentsUnits – 1;
// – 1 es un indice basado en 0x
 
Thread.Sleep(UnitSevenSegmentLedDelay);
}
}
else
{
int ledUnit = 0; // indice basado en 0
for (int i = 0; i < stringToShow.Length; i++)
{
string eachLetter = stringToShow.Substring(i, 1);
Show(eachLetter, ledUnit);
ledUnit += 1;
 
// Si longitud de stringToShow es mayor
//que SevenSegmentsUnits restalo
ledUnit = ledUnit % SevenSegmentsUnits;
 
Thread.Sleep(UnitSevenSegmentLedDelay);
}
}
 
Thread.Sleep(FlickerDelay);
}
 
}

El tercer método Mostrar toma dos argumentos, primero es la cadena que se mostrará y segundo es dónde mostrara es decir, en  que bumero de display LED. En la HashTable definida durante la construcción, se rellena  la matriz correcta de Boole  y entonces el pin correspondiente se establece a nivel alta o baja en base a esta matriz booleana. En el paso final, todos los pines asociados al  ánodo o al cátodo común se establecen a nivel bajo de modo que sólo el  LED apropiado se establece a nivel  alto.

public void Show(string numberString, int ledUnit)
{
bool[] ledSegmentOnOffValues;
numberString = numberString.ToLower();
 
// en este nivel, se admite la longitud de la cadena, por lo que descarta el resto
if (numberString.Length > 1) numberString =
numberString.Substring(numberString.Length – 1, 1);
 
// Enviar nivel bajo al ánodo / cátodo común de SevelSegmentLED
for (int i = 0; i < ledSegmentUnit.Length; i++)
{
ledSegmentUnit[i].Write(false);
}
 
if (!ledSegmentTable.Contains(numberString))
{
// cuando se pasas una letra no soportada muestra  «-«
ledSegmentOnOffValues = (bool[])ledSegmentTable[«-«];
}
else
{
// consigue el array a  true/false 
ledSegmentOnOffValues = (bool[])ledSegmentTable[numberString];
}
 
for (int i = 0; i < segmentPins.Length; i++)
{
//poner el  pin correspondiente a nivel alto
segmentPins[i].Write(ledSegmentOnOffValues[i]);
}
 
// solamente envia la señal al catodo o anodo seleccionado
ledSegmentUnit[ledUnit].Write(true);
}

Valores  maximos y/o minimos

Con muy pocas líneas de código podemos ampliar o añadir funcionalidades adicionales como un contador que toma cuenta del valor  mínimo al valor máximo. Este contador es un ejemplo muy simple que toma dos argumentos, el valor mínimo y el valor máximo. Un bucle for se puede configurar  a partir de este minuto a valor máximo y el método Show que se ha llamado de pasar el incremento de bucle de corriente. Este método nos permite mostrar el contador en nuestros siete segmentos unidad LED

 

public void Counter(int minValue, int maxValue)
{
for (int i = minValue; i <= maxValue; i++)
{
Show(i);
Debug.Print(i.ToString());
}
}

Pruebas finales

Con nuestra clase SevenSegments, tenemos varias salidas. En primer lugar vamos a ver la salida de nuestro circuito. Aquí podemos ver el valor más bajo en nuestra pantalla cuando LDR está cubierto sin embargo el número aumenta a medida que iluminamos nuestro LDR.

Ahora echemos un vistazo a nuestro métodoque hemos añadido a nuestra clase SevenSegments. Con el siguiente código, po rjemplo vamos a ver los números  desde  980 a 1020:
sevenSegments.FlickerDelay = 5;
sevenSegments.UnitSevenSegmentLedDelay = 1;
sevenSegments.UnitRepetition = 5;
sevenSegments.RightToLeft = true;
while (true)
{
sevenSegments.Counter(980, 1020);
}

 

Vamos a darle una cadena de más de nuestros Siete unidades LED del segmento y  ver qué pasa:

sevenSegments.FlickerDelay = 10;
sevenSegments.UnitSevenSegmentLedDelay = 500;

sevenSegments.UnitRepetition = 1;

sevenSegments.RightToLeft = false;
while (true)
{
sevenSegments.Show(«1234567890abcdefghijklmnopqrstuvwxyz»);
sevenSegments.Show(«????»);
sevenSegments.Show(«Embedded-Lab»);
 
}

Ahora, vamos a ajustar algunas de sus propiedades y ver un efecto de laminación

sevenSegments.FlickerDelay = 5;

sevenSegments.UnitSevenSegmentLedDelay = 200;
sevenSegments.UnitRepetition = 50;

sevenSegments.RightToLeft = false;
while (true)
{
sevenSegments.Show(«-Lab»);
}

 

Y para terminar , es el siguiente video podemos ver el código presentado ejecutándose con la electrónica descrita

Los display leds de 7 segmentos  ( o mas ) como se puede ver son bastante sencillos de manejar  desde Netduino  gracias a la  multiplexacion como hemso visto en el ejemplo

Fuente   aqui

Por fin disponible la nueva version 3 de la famosa pulsera de Xiami Mi Band 3


En efecto, tras muchos meses de misterio por fin se ha desvelado tanto el precio  como  la disponibilidad de la version 3 de la famosa pulsera cuantificadora de Xiami , la cual ya esta disponible en España desde ayer  por 32€  en Amazon (eso si  unos 2€ más  caro del precio filtrado hace unas semanas)

También  aproximadamente a partir de la semana que viene ( estiman sobre el 14 de septiembre) será posible su compra en el resto de tiendas y grandes superficies con alianzas con la firma china.

Ha mejorado en muchos aspectos destacando la estética gracias a su nueva pantalla , que de hecho ya no son compatibles las bandas de silicona que hacen de correa  con las de la version anterior Mi2 debido a su mayor tamaño  . Desgraciadamente  Xiami no ha incluido el chip NFC , suponemos para no empeorar su excelente autonomía de unos 20 días .

Ver imagen en Twitter

 

Características de la Xiaomi Mi Band 3

Puede que la espera  haya merecido la pena pues esta nueva version  mejora las prestaciones de la anterior  Xiaomi Mi Band   destacando   sobre todo una pantalla OLED -táctil– de mayores dimensiones de 0,78″    y  especialmente la resistencia al agua con certificación IP67  lo cual permite sumergirla hasta   50 metros , haciéndola ideal para   natación.

La nueva pulsera de mijo 3 también puede mostrar el nombre o el número de la persona que llama si no quiere contestar de modo que al  presionarla largamente puede rechazar la llamada.

Ademas , se mantienen algunas de  las características  que ya tenia la version anterior, pero casi siempre mejorando algun aspecto de estas:

  • Visualización en tiempo real de la duración del ejercicio, kilometraje, frecuencia cardíaca.
  • Administración de la salud durante todo el día
  • Podómetro más preciso, ritmo cardíaco, monitoreo de la calidad del sueño, recordatorio sedentario
  • Podómetro diario.
  • Monitorizacion de frecuencia cardíaca
  • Puede actualizarse el algoritmo de número de pasos nuevamente para que sus esfuerzos cuenten en cada paso.
  • El sensor de frecuencia cardíaca puede leer con precisión los cambios de la frecuencia cardíaca durante 24 horas y también puede detectar la frecuencia cardíaca actual en cualquier momento.
  • Autonomía de hasta 20 días  gracias a su batería de 110 mAh

Asimismo, hemos de sumar conectividad Bluetooth 4.2 para sincronizar con el móvil y ofrece al usuario multitud de funciones similares  al version anteior como la presentación de la hora, alarma con vibrador, seguimiento de pasos y actividad física, monitorización de las horas y calidad del sueño, así como la lectura de otros muchos datos y estadísticas relacionadas con la salud.

 La pulsera viene en español  si se compra desde España , aunque en caso de venir en chino,  después de conectar con el APP «MI FIT» , se actualizaría  el firmware de esta  junto el idioma de la app al español automáticamente( es  decir, en cuanto la app de la pulsera detecta el reloj, se actualiza al idioma al español  sin mas intervención). Una vez actualizado, funciona perfectamente en español, sin ningún problema para configurarlo.

En esta version ademas se  pude acceder a un cronómetro,  hacer búsquedas de teléfono con pitido, e incluso  nos permite  elegir  entre 3 tipo de esferas.

Gracias a la nueva aplicación Xiaomi Sports ademas  permite hacer un seguimiento profundo de nuestra actividad física  pudiendo establecer las necesidades diarias de acuerdo con su propia situación.

Si bien   ya funcionaba bien en la version anterior , el sensor de pasos de esta version es una mas preciso   gracias al  uso de un nuevo algoritmo .
Basta elegir  el programa de acondicionamiento físico que más le convenga y  para poder hacer un seguimiento diaria de nuestro avance  pidiendo  controlar regularmente los datos del sueño,evolución del  ritmo cardíaco, calorías quemadas, km recorridos  y un largo etcétera.

appxiaomi.PNG

En resumen   mejora muchas  aspectos sutilmente de la version anterior Mi2   de modo que  merece la pena frente a  al anterior version   porque gracias a su  mayor pantalla  mejora de forma evidente  las notificaciones, por ejemplo  con funciones útiles, ampliables mediante aplicaciones de terceros (como leer los whatsapp/correos recibidos).

Ademas no debemos olvidar que han añadido certificación IP67  lo cual permite sumergirla hasta   50 metros ,  lo cual la hace un mas versátil para  otros usos  como por ejemplo natación si bien en este campo no mide  tan bien los metros como al  andar o correr

En definitiva, una buena compra destacando las gran cantidad a de prestaciones  propias de relojes inteligentes  eso si por un precio reducido