Error:(23, 17) Failed to resolve: junit:junit:4.12 en Android Studio


Este problema como vamos a ver, no se resuelve desinstalando  y volviendo a instalar Android Studio

El error   completo  ocurre cuando intentamos probar cualquier proyecto  ( incluso vacío ) ,   apareciendo el mensaje  Error:216 Failed to resolve: junit:junit:4.12

 

error

 

A continuación citamos los pasos para solucionar el problema:

  • Cerrar Android Studio
  • Descargar  el paquete junixfixerfile.zip   que contendrá  la librería junit-4.12.jar ,por ejemplo a partir de este enlace contrastado http://www.mediafire.com/file/413j0qfiixb4tda/junitfixerfile.zip
  • Descomprimir  el fichero con el winrar , seleccionando  la ruta    de las librerías de la aplicación  ,por  ejemplo  en la ruta  C:\Users\xxxxxxxxx\AndroidStudioProjects\MyApplication\app\libs (donde  xxxxx es su usuario logado en windows)

androidstudio1

 

 

 

 

 

 

 

 

 

 

 

 

 

  • Ahora ya puede abrir Android Estudio, volver a cargar su proyecto e intentar ejecutar su proyecto pues no debería dar ningún error

 

En caso de que seguidos los pasos anteriores persista el error , debería eliminar la  inferencia a la librería  Junit antigua  y colocar en su lugar la nueva librería.

Esto se hace pulsando  en File–>Proyect Structure.

Aquí , nos iremos a nuestra app( Modules–>App) y seleccionaremos Dependencies

 

Deependencias

Aquí deberíamos posicionarnos sobre la libreria junit  y darle el botón – (Remove)

Acto seguido daremos a añadir con el botón + ( a la derecha), seleccionaremos Libraries Deependencies –>Files dependencies   y nos  iremos a la ruta donde la nueva almacenamos  la nueva librería ( C:\Users\xxxxxxxxx\AndroidStudioProjects\MyApplication\app\libs)

Finalmente le damos a “Compile”  y  ya debería poderse ejecutar sin problemas sin volver a dar el error

Anuncios

Gradle sync failed: CreateProcess failed, error=216 con Android Studio


Para todos aquellos que se inician en el desarrollo de aplicaciones  para Android, es importante tener claro que entorno de desarrollo es el mejor y más completo para empezar con la primera aplicación, pues ese primer proyecto quizás  un buen día, pueda convertirse en una app de uso masivo y por lo tanto, reportar beneficios económicos.

Al principio  había desarrolladores  que usaban NetBeans , pero poco  después todas  la comunidad se paso programar  con  Eclipse   hasta  que salió a la luz Android Studio, que o todo apunta a que será el entorno que use todo el mundo pues en poco tiempo será lo único que el equipo de Android recomiende.

Está basado en IntelliJ IDEA, uno de los IDE para java de primer nivel (entre los mejores, con Eclipse, netbeans)

Ademas  soporta un  nueva forma de construir los apk. Más serio, mas versátil, mas potente, mas actual, y mas parecido a un proyecto en java.

En este post vamos a intentar solucionar un  típico  problema cuando empezamos a  desarrollar con  Android Studio  en equipos no muy modernos.

Este problema como vamos a ver, no se resuelve reinstalando   Android Studio

El error   completo  ocurre cuando intentamos probar cualquier proyecto  ( incluso vacío ) ,   apareciendo el mensaje “Gradle sync failed: CreateProcess failed, error=216 Consult IDE log for more details (Help | Show Log)”

Este es  un ejemplo:

error

 

El error  216  , que en ocasiones no es mostrado completo corresponde a este descriptivo “This version of %1 is not compatible with the version of Windows you’re running. Check your computer’s system information and then contact the software publisher

Esto sucede porque se incluye la versión de  64bit del JRE con Android Studio para Windows, lo cual  produce errores en sistemas de 32 bits.

La solución al problema pasa por dos pasos:

 

  • No utilice el JDK incorporado: vaya al cuadro de diálogo Archivo -> Estructura del proyecto, desmarque “Usar JDK incrustado” y seleccione el JRE de 32 bits que tenga instalado por separado en su sistema . Al menos debería ser  JDK8  o superior  .

 

android_studio

 

 

  • Disminuya la huella de memoria para Gradle en gradle.properties (Propiedades del proyecto), por ejemplo, establezca en -Xmx768m ( tendrá por defecto -Xmx1024m).Es decir debería quedar así:
org.gradle.jvmargs= -Xmx768m

Programar en Andoid ya no es tan complicado (parte 1)


Android es un s.o .basado en el núcleo Linux  que aparece en octubre de 2003 no en Google sino en la empresa Android In , empresa que mas tarde seria adquirida por Golgle.  Android fue presentado en 2007 junto la fundación del Open Handset Alliance (un consorcio de compañías de hardware, software y telecomunicaciones) para avanzar en los estándares abiertos de los dispositivos móviles vendiéndose  el primer móvil con el sistema operativo Android ( HTC Dream) en octubre de 2008.Los dispositivos de Android venden más que las ventas combinadas de Windows Phone e IOS .

Según Symantec en comparación con iOS, Android es un sistema explícitamente menos vulnerable  citando  13 vulnerabilidades graves para Android y 387 vulnerabilidades graves para iOS. El estudio también habla de los ataques en ambas plataformas, y en este caso Android se queda con 113 ataques nuevos en 2012 a diferencia de iOS que se queda en 1 solo ataque. Incluso así Google y Apple se empeñan cada vez más en hacer sus sistemas operativos más seguros incorporando más seguridad tanto en sus sistemas operativos como en sus mercados oficiales.

 

Tradicionalmente  para programar en Android se requerían bastantes herramientas que habia que configurar  manualmente : en primer lugar  teníamos que irnos a la página de Oracle en la sección de descargas, y  buscar el Java JDK (Java Development Kit) y descargar e instalarlo, despues  teníamos que descargar la versión de Eclipse especial  para Java (Eclipse IDE for Java Developers)  que al igual que en el paso previo  , tenia  que estar en consonancia  con la  versión de sistema operativo  y el procesador…

El siguiente paso era descargar el SDK que  nos proporciona Google, donde es ahí en realidad TODO lo que necesitamos para desarrollar: documentación, ejemplos, iconos Finalmente  a diferencia de todo lo descargado e instalado, el ultimo  paso (el más largo) era instalar el ADT dentro de Eclipse y configurarlo para que funcionaran todas las herramientas  dentro del propio Eclipse.

Afortunadamente  todos estos pasos comentados anteriormente comentados , aunque hay aun muchos des arrolladores que siguen en la actualidad usándolos, actualmente se han simplificado en un único paso : descargando e instalando una única  herramienta recomendada por Google : Android Studio.

 

androis-studio

Antiguamente se instalaba el Eclipes, Java , el DSK , pero como hemos vistos la opción mas recomendada actualmente  es descargar e instalar la herramienta recomendada por Google que puede descargar desde aqui: Android Studio.

Este nuevo sw de Google incluye todas las herramientas necesarias para desarrollar con Android incluso su propia  versión de java de 64 bits por lo que deberemos tener en cuenta que en principio solo deberíamos instalar en una maquina actual con arquitectura de 64bits

Una vez  instalada la herramienta

  1. En Android Studio, cree un nuevo proyecto:
    • Si no tiene un proyecto abierto, en la ventana Welcome to Android Studio haz clic en Start a new Android Studio project.
    • Si tiene un proyecto abierto, selecciona File > New Project.
  2. En la pantalla New Project, ingresa los siguientes valores:
    • Nombre de la aplicación: “My First App”
    • Dominio de la empresa: “example.com”

    Android Studio completara el nombre del paquete y la ubicación, pero puede editar estos datos si lo desea.

  3. Haga clic en Next.
  4. En la pantalla Target Android Devices, conserva los valores predeterminados y haz clic en Next.El SDK mínimo requerido es la primera versión de Android que admite su app, lo cual se indica a través del nivel de API. Para lograr la compatibilidad con la mayor cantidad posible de dispositivos, debe establecer esto en la versión más antigua disponible que permite a su app proporcionar su conjunto de funciones fundamentales.
  5. En la pantalla Add an Activity to Mobile, selecciona Empty Activity y haz clic en Next.
  6. En la pantalla Customize the Activity, conserve los valores predeterminados y haz clic en Finish.

Después de procesar, Android Studio se abre y aparecerá la estructura de una app “Hello World” con varios  archivos predeterminados. Por supuesto  podemos  agregar funcionalidad a algunos de estos archivos, como veremos en  un siguiente post.

Ahora es tiempo de  revisar los archivos más importantes. Primero, asegúrese  de que la ventana Project esté abierta (selecciona View > Tool Windows > Project) y la vista Android esté seleccionada en la lista desplegable de la parte superior. Podrás ver los siguientes archivos:

  • app > java > com.example.myfirstapp > MainActivity.java:Este archivo aparecerá en Android Studio después de que finalice el Asistente de proyecto nuevo. Contiene la definición de clase de la actividad que creo anteriormente. Cuando compila y ejecuta la app,  Activity inicia y carga el archivo de diseño con el mensaje “Hello World!”.
  • app > res > layout > activity_main.xml: es el archivo XML que define el diseño de la actividad. Contiene un elemento TextView con el texto “Hello world!”.
  • app > manifests > AndroidManifest.xml: es el archivo de manifiesto  que describe las características fundamentales de la app y define cada uno de sus componentes  (botones , cajas de texto , fondos , etc. )
  • Gradle Scripts > build.gradle:Android Studio usa Gradle para compilar y generar tu app. Existe un archivo build.gradle para cada módulo de tu proyecto, así como también un archivo build.gradle para el proyecto entero. Generalmente, solo será importante el archivo build.gradle del módulo. En este caso, es el app o módulo de aplicación.

 

Después  de comprobar la estructura de un programa básico en  Android , toca configurar su dispositivo físico Android  para probar el código pues lo cierto es que aunque es posible hacerlo con emulador lo ideal es mejor hacerlo sobre un terminal físico .

Este paso o se hace de la siguiente manera:

  1. Conecte su dispositivo a su máquina de desarrollo con un cable USB. Si está desarrollando en Windows, es posible que necesite instalar el controlador USB adecuado para su dispositivo (para obtener ayuda para instalar los controladores, consulte el documento Controladores OEM USB).
  2. Habilite USB debugging en el dispositivo. Para ello, dirígase a Settings > Developer options. (En Android 4.2 y versiones posteriores, Developer options está oculto de manera predeterminada. Para que esté disponible, diríjase a Settings > About phone y presiona Build number siete veces. Cuando regreses a la pantalla anterior, verás Developer options.)

Ejecute su app desde Android Studio de la siguiente manera:

  1. En Android Studio, seleccione su proyecto y haga clic en Run en la barra de herramientas.
  2. En la ventana Select Deployment Target, selecciona su dispositivo, y haga clic en OK.
  3. Android Studio instalara la app en su dispositivo conectado y lo iniciara automáticamente

!Enhorabuena  ya ha creado su propia app para Android, y de hecho ya tenemos las bases para desarrollar cualquier cosa  que se nos ocurra!

Un monopatin controlado por una Raspberry Pi


Es cierto  que existen muchos  proyectos de Skateboard eléctricos caseros pues de hecho una simple búsqueda del termino “diy electric skateboard” en  youtube nos da  bastantes ideas al respecto , pero  en este prototipo su originalidad reside  precisamente en  ser el primero skate eléctrico  cuya  controladora principal es una Raspberry Pi,  lo cual nos debería  animar a usar  esta estupenda placa para muchas tareas similares , como por ejemplo cualquier otro proyecto de movilidad eléctrica  como podría ser el cualquier controlador para un motor brushless usados muy comúnmente en   bicicletas eléctricas.

El proyecto fue parte de un  trabajo de la universidad, donde el requisito previo era construir cualquier cosa con un Raspberry Pi y desde luego la idea es realmente interesante e inspiradora .

Dado  que solo se usa  un motor brushless , se utilizan  3 pines  del GPIO ( como puede verse en  la imagen): se utilizan el rojo para +5V , blanco del GPIO2 para transmitir la señal PWM (Modulación de Pulso)  para el ESC y el negro para la masa .

Par el control se puede utilizar un modulo bluetooth conectado a un puerto usb si es un modelo antiguo ( la nueva Raspberry pi 3 ya lo lleva integrado)

Lógicamente en la raspberry se alberga  un pequeño programa en Python  que gestiona el motor gracias a las ordenes que recibe via bluetooth del mando

raspberr

El controlador del motor ( una cajita roja que hay juntos la Raspberry Pi  en un lateral ) es el famoso controlador VESC ,  el cual basa su éxito por  la  capacidad de frenado regenerativo, es decir es capaz de invertir el  uso del motor como alternador cuando el motor no gobernado por la RP, usar el propio motor como alternador gracias a la electrónica interna  poder  cargar las baterías por ejemplo en los descensos.

 

r2.png

Respecto al elemento motriz se utiliza un motor Turnigy Aerodrive SK3 – 6374-149kv Brushless Outrunner Motor , es decir un motor sin escobillas de alto rendimiento al que se le ha acoplado una correa que engrana directamente con el eje de la rueda delantera

Turnigy SK3 Motors  es un motor eficiente sin escobillas de alta calidad que  usa cojinetes blindados dobles, imanes de neodimio sinterizado y un estator especial para  asegurar una precisa y consistente fcm en cada devanado .  Sus características son las siguientes:

  • Turns: 18T
  • Voltage: 12S Lipoly
  • RPM/V: 149kv
  • Internal resistance: 0.021 Ohm
  • Max Loading: 70A
  • Max Power: 2250W
  • Shaft Dia: 8.0mmBolt
  • holes: 32mmBolt
  • thread: M4
  • Weight: 840gMotor
  • Plug: 4.0mm Bullet Connector

 

Respecto a la energía , destacar que se usan dos baterías de Lipo asidas al cuerpo del skate con un belcro con idea de poder extraerlas para cargarlas   .La conexión de las dos baterías es en paralelo y la capacidad de cada bateria es de 2200mAh de  11,15V .

El modo de conexión al ser paralelo  se hace  simplemente uniendo rojos con negros en un conector  para  disponer de dos únicos cables de salida . Es importante destacar que  sus cables de carga permanecen  independientes   . Las baterías son las usadas en aeromodelismo de  Li-Polímero de 11.1V

bateriua.png

Y ahora podemos ver la Raspberry Pi m  ,el motor  y las baterías     con todo el  interior  montado

patin

Aparte del enorme motor necesario para que funcione junto a las baterías, utiliza como mando de control un mando de la Wii que ya que tiene gatillo sirve como medida de seguridad.

El conjunto como contabamos anteriormente mse completa con un receptor bluetooth que se encarga de recibir la señal del mando de la wio  junto con un pequeño script en Python   que permite controlar el variador

 

En el siguiente video podemos ver al orgulloso autor explicando el montaje asi como haciendo una pequeña demostración de su invento funcionando

 

 

 

Un robot con su Raspberry Pi


En efecto , con un mando Wiimote de Nintendo (en Amazon  cuesta menos de 16€ ), junto con  su  Raspberry Pi 2 Model B  puede  crear su propio “robot mayordomo” eso si usando  una plataforma que le de movilidad al conjunto .

2016-03-27_18h23_36     2016-03-27_23h10_21

Evidentemente la forma del robot quedara sujeta a sus gustos, a los materiales que emplee y por supuesto a su creatividad ,pero el resultado siempre sera muy interesante sobre todo por el alto grado de personalización al que puede llegar  . Lógicamente, ademas  de la Raspberry  y el mando wiimote , también necesitará comprar un chasis  con las dos orugas motorizadas   para que el robot pueda moverse.

Aunque el resultado probablemente no este a la altura de los grandes desarrollos de   robots industriales , al hacer este robot aprenderá cómo utilizar Bluetooth para comunicarse con su Raspberry Pi, cómo conectar una tarjeta de robótica básica usando los pines GPIO ( y controlarlos con Python)  ,así como también cómo utilizar una Nintendo Wiimote para controlar su Raspberry Pi ( también usando  Python)

Para empezar ,siempre es bueno descomponer proyectos complejos en otros mas  pequeños proyectos  , ya que esto  hace que sea mucho más fácil de resolverlos. Es decir: si hace este proyecto de una sola vez y no funciona , ¿cómo saber si es la tarjeta del motor , los motores , la conexión Bluetooth o el programa el culpable del fallo?

Como referencia ,los pasos a  seguir en la construcción podrían ser los siguientes:

  1. Configurar y probar la tarjeta del motor y los motores
  2. Configurar y probar la conexión Bluetooth
  3. Configurar y probar el Wiimote
  4. Escribir el programa definitivo
  5. Construir el cuerpo de su robot  usando su creatividad

Montaje inicial

Para poder controlar los motores del grupo motor , necesitará un escudo  que tendrá que intercalar entre los pines del GPIO  de su Raspberry   y los cables de alimentación de los dos motores DC. Para ello simplemente  ponga la placa  encima de  los pines del GPIO de su Raspberry PI cuidando el orden . Debería  tener un aspecto como este:

 

2016-03-26_19h38_28

Un vez conectado el escudo, el siguiente paso es conectar los cables  de uno de los  motores al conector azul marcado J3 / M1 , utilizando cables pelados en cada extremo o cables  usando un conector macho – macho . Obviamente  también debe conectar el otro motor para J2 / M2 .

El Rover 5 utiliza 2 motores independientes , cada uno con un codificador de cuadratura óptica y la caja de cambios . El montaje de la caja de cambios completo puede hacerse girar a incrementos de 5 grados para diferentes configuraciones de despacho . Puede incluso sustituir a las orugas de los tanques con ruedas tradicionales .

Esto no es una base de robot endeble :con un peso de más de 2,5 libras sin baterías , esta base es resistente y puede pasar por encima de casi  todo.

No importa  en qué forma conecta cada motor individual en este punto (si es un motor gira en la dirección equivocada entonces simplemente puede intercambiar los cables de otro ). Ademas en este punto también puede conectar la alimentación  que simplemente puede  proporcionarse por un portapilas de 6 pilas AAA de 1,5V , el cual  proporcionara los 6V necesarios para el escudo Ahora tiene una batería conectada a los motores del robot a través de la tarjeta de control del motor .

Atención :tenga cuidado con la polaridad: el cable rojo del portapilas debe conectarlo al terminal +VCC   del escudo  y el cable negativo al terminal GND o 0V del escudo.

El aspecto final debería ser algo similar al siguiente :

2016-03-27_00h27_54

El ultimo paso es conectar  la Raspberry  Pi al escudo  con lo que ya tendríamos conectados   todos los elementos del  robot.

Ahora  lo siguiente que toca es dotar del sw necesarios en la  Raspberry Pi para controlar cómo y cuándo los motores reciben energía .


Prueba de motores

La placa  Ryanteck se controla mediante los pines  GPIO  17 , 18, 22 y 23 de la Raspberry  Pi . Si establece el pin  17 a nivel alto  , un motor va hacia la derecha , mientras que si se activa a nivel alto el pin 18 , el  motor  gira en sentido antihorario . Los  pines  22 y 23 dan  control del motor 2 funcionando de un modo idéntico a los pines 17 y 18 pero con el motor 2.

Con todo el conjunto conectado a  su Raspberry Pi  vamos a escribir un pequeño script en Python para probar  el  funcionamiento de la base motorizada .

En la línea de comandos  escriba  test_motors.py tipo nano .

Ahora escriba en el siguiente programa:

import RPi.GPIO as io
import time

io.setmode(io.BCM)
pins = [17, 18, 22, 23]
for pin in pins:
  io.setup(pin, io.output)

#Los motores de prueba  giran a  un lado y luego al otro con retardo de 0,5 segundos .
for pin in pins:
  print ('Testing pin ' + str(pin))
  io.output(pin, 1)
  time.sleep(0.5)
  io.output(pin, 0)

Presione Ctrl-O y luego Enter para guardar . Pulse CTRL – X para salir de la línea de comandos . Ahora ejecute el programa de prueba : sudo test_motors.py pyton .

Si la prueba no se ejecuta como se esperaba , compruebe todas las conexiones así como la batería y vuelva a intentarlo .

 

Prueba  bluetooth

Otro modulo que usted necesitará es un adaptador Bluetooth . Teniendo conectividad Bluetooth se puede utilizar para transferir archivos y para la comunicación , pero  también le permite utilizar dispositivos de juego como en la Nintendo Wiimote y el controlador de PS3 para aplicaciones de  robótica .No todos los adaptadores funcionan en el Pi ; no se puede recomendar específicamente cualquier Inateck pero el adaptador de Bluetooth 4.0 que estamos utilizando funciona muy bien.

Para la prueba  del mando de  la Nintendo es habitual usar  el dongle Inateck Bluetooth Adaptador USB 4.0 con LED | Dongle inalámbrico con inactivo inteligente y Wake-Up | Compatible con Windows XP / Vista / 7/8 / 8.1 | Soporte EDR y A2DP estéreo | Broadcom Chipset – Negro , el cual usa un chip Broadcom 20702, el chip Bluetooth más reconocida en Europa y América; Nivel 1, la distancia de transmisión de hasta 10 m; Velocidad de transmisión máxima de 3 M / S.Ademes.Este dongle emite una señal de Bluetooth 4.0, es estable y fuerte,  usa modo dúplex  y  tiene un  bajo consumo de energía.Ademas cuenta con  ahorro de energía a través de los modos inteligentes de sueño y despertar, evita la interferencia de monitoreo CRC de 24 bits y usa  modulación de frecuencia automática contra superposiciones

2016-03-27_18h41_12

 

Enchufe el adaptador Bluetooth en el puerto USB de la Raspberry Pi , arránquela y   conectese  a esta  .

Procedeamos a instalar el sw necesario,para ello desde línea de comandos debería instalar el driver usando el siguiente comando:

>sudo apt-get install –no-install-recommends bluetooth

Una vez instalado el software ,debería ver el bluetooth está en marcha,para ello escriba:

>sudo service bluetooth status

Deberia dar el mensaje bluetooth is running.

Si no es así, reinicie la Raspberry Pi   y vuelva a intentarlo .

Para probar el dongle  escriba

>hcitool  scan

Cualquier dispositivo detectable  por  Bluetooth en la zona aparecerá en la pantalla ; lo cual indicará  que ahora está listo para usar Bluetooth en el Raspberry Pi . Si no se ve nada , asegúrese de que usted tiene un teléfono u otro dispositivo compatible con Bluetooth cerca del Pi y pruebe a  detectarlos.

 

Prueba de conexión  del mando  .

Antes de continuar,  debe tener Bluetooth instalado y funcionando en su Raspberry Pi  ( habiendo seguido todos los pasos  anteriores ).  El hecho de que el servicio de Bluetooth esté en funcionamiento y pueda ver otros dispositivos no significa que el dongle bluetooth sea capaz de ver el Wiimote( de hecho también puede tener problemas si está utilizando un mando Wiimote diferente del oficial).Así que no hay reglas seguras y rápidas; puede que tenga que probar diferentes configuraciones si tiene problemas.

Escriba desde linea de comandos:

>hcitool scan

Ahora pulse los botones ‘1’ y ‘2’ en su Wiimote al mismo tiempo:los LEDs azules deben parpadear en el Wiimote y debería ver algo como esto en la pantalla:

Scanning … 00:1E:02:8A:CD:A1 Nintendo RVL-CNT-01

También puede ver otros dispositivos Bluetooth que están dentro del alcance, pero obviamente  puede hacer caso omiso de ellos.

Si todo ha ido correctaemmnte ,ahora se sabe que la función Bluetooth está funcionando y  puede comunicar el Wiimote con su Raspberry Pi.

El último paso es asegurarse de que podemos hablar con el Wiimote usando Python.,para lo cual debe instalar el módulo CWIID ,con objeto de que desde Python puede hablar con el Wiimote. 

>sudo apt-get install python-cwiid.

 

El siguiente programa probará que el Wiimote puede comunicarse con el Raspberry Pi. En la línea de comandos teclee

>nano wii_remote_1.py

Luego escriba o copie y pegue el código siguiente:

#!/usr/bin/python
#+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
#|R|a|s|p|b|e|r|r|y|P|i|-|S|p|y|.|c|o|.|u|k|
#+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
#
# wii_remote_1.py
# Connect a Nintendo Wii Remote via Bluetooth
# and  read the button states in Python.
#
# Project URL :
# http://www.raspberrypi-spy.co.uk/?p=1101
#
# Author : Matt Hawkins
# Date   : 30/01/2013

# -----------------------
# Import required Python libraries
# -----------------------
import cwiid
import time
#import RPi.GPIO as io

#io.setmode(io.BCM)
#pins = (2,3,4,17)
#for i in pins:
#  io.setup(i,io.OUT)

button_delay = 0.1

print 'Press 1 + 2 on your Wii Remote now ...'
time.sleep(1)

# Connect to the Wii Remote. If it times out
# then quit.
try:
  wii=cwiid.Wiimote()
except RuntimeError:
  print "Error opening wiimote connection"
  quit()

print 'Wii Remote connected...\n'
print 'Press some buttons!\n'
print 'Press PLUS and MINUS together to disconnect and quit.\n'

wii.rpt_mode = cwiid.RPT_BTN
 
while True:

  buttons = wii.state['buttons']

  # If Plus and Minus buttons pressed
  # together then rumble and quit.
  if (buttons - cwiid.BTN_PLUS - cwiid.BTN_MINUS == 0):  
    print '\nClosing connection ...'
    wii.rumble = 1
    time.sleep(1)
    wii.rumble = 0
    exit(wii)  
  
  # Check if other buttons are pressed by
  # doing a bitwise AND of the buttons number
  # and the predefined constant for that button.
  if (buttons & cwiid.BTN_LEFT):
    print 'Left pressed'
    time.sleep(button_delay)         
    #io.output(2, True)

  if(buttons & cwiid.BTN_RIGHT):
    print 'Right pressed'
    time.sleep(button_delay)          
    #io.output(3, True)

  if (buttons & cwiid.BTN_UP):
    print 'Up pressed'        
    time.sleep(button_delay)          
    #io.output(4, True)
    
  if (buttons & cwiid.BTN_DOWN):
    print 'Down pressed'      
    time.sleep(button_delay)  
    #io.output(17, True)
    
  if (buttons & cwiid.BTN_1):
    print 'Button 1 pressed'
    time.sleep(button_delay)          

  if (buttons & cwiid.BTN_2):
    print 'Button 2 pressed'
    time.sleep(button_delay)          

  if (buttons & cwiid.BTN_A):
    print 'Button A pressed'
    time.sleep(button_delay)          
    #for i in pins:
      #io.output(i, False)    

  if (buttons & cwiid.BTN_B):
    print 'Button B pressed'
    time.sleep(button_delay)          

  if (buttons & cwiid.BTN_HOME):
    print 'Home Button pressed'
    time.sleep(button_delay)           
    
  if (buttons & cwiid.BTN_MINUS):
    print 'Minus Button pressed'
    time.sleep(button_delay)   
    
  if (buttons & cwiid.BTN_PLUS):
    print 'Plus Button pressed'
    time.sleep(button_delay)

 

 

Cuando haya terminado: Presione Ctrl-O y luego Enter para guardar Presione CTRL-x para salir de la línea de comandos .

Ahora ejecute el programa de prueba tecleando

>sudo python wii_remote_1.py

Siga las instrucciones y debería ver la pantalla respuestas a todas sus pulsaciones de botón  así que ha llegado hasta aquí, ya sólo le queda probar todo el conjunto.

 

A continuación  vamos  a ver  el programa principal que le permitirá controlar el vehículo con el Wiimote

En la línea de comandos escriba lo siguiente:

>nano robot.py

Ahora puede  escribir  , o cortar y pegar, el siguiente  programa .

#!/usr/bin/python
#based on Matt Hawkins' code http://www.raspberrypi-spy.co.uk/?p=1101
#Re written by Ryan Walmsley

import cwiid
import time
import RPi.GPIO as io

io.setmode(io.BCM)
#Motor 1 is designed to be the motors on the left, Motor 2 is designed to be on the right
#If one motor is in the wrong direction you can swap the pins around to save you having to re-wrire the robot.
m1a = 17 #Motor 1 Forwards
m1b = 18 #Motor 1 Backwards
m2a = 22 #Motor 2 Forwards
m2b = 23 #Motor 2 Backwards
pins = (m1a,m1b,m2a,m2b)
for i in pins:
  io.setup(i,io.OUT)

for i in pins:
  io.output(i,False)

button_delay = 0.1

print 'Press 1 + 2 on your Wii Remote now ...'
time.sleep(1)

# Try to connect to the Wiimote & quit if not found
try:
  wii=cwiid.Wiimote()
except RuntimeError:
  print "Can't connect to Wiimote"
  quit()

print 'Wiimote connected'
wii.rpt_mode = cwiid.RPT_BTN
 
while True:
  buttons = wii.state['buttons']
  if (buttons & cwiid.BTN_UP):
    #Forwards
    time.sleep(button_delay)    
    io.output(m1a, True)      
    io.output(m2a, True)
   
  elif (buttons & cwiid.BTN_DOWN):
    time.sleep(button_delay)  
    io.output(m1b, True)
    io.output(m2b, True)
  
  elif (buttons & cwiid.BTN_LEFT):
    time.sleep(button_delay)         
    io.output(m1a, True)
    io.output(m2b, True)
   
  elif(buttons & cwiid.BTN_RIGHT):
    time.sleep(button_delay)          
    io.output(m1b, True)
    io.output(m2a, True)
  
  else:
    io.output(m1a, False)
    io.output(m1b, False)
    io.output(m2a, False)
    io.output(m2b, False)
   

    
#press button A to stop all motors
  if (buttons & cwiid.BTN_A):
    time.sleep(button_delay)          
    for i in pins:
      io.output(i, False)    

 

Cuando haya terminado : Presione Ctrl-O y luego Enter para guardar pulse CTRL – x para salir de la línea de comandos .

Ahora ejecute el programa :

>sudo python robot.py.

Si todo funciona correctamente usted debería ser capaz de controlar su vehículo con el Wiimote . Si no es así , vuelve a atrás y compruebe que cada paso está funcionando correctamente ..

Ahora usted ya tiene un robot con control remoto , que es completamente funcional  , pero obviamente acaba de empezar , pues tendrá que pensar en el contenedor  donde lo va a ubicar  ( tendrá que usar su imaginación ) así  como si le va a añadir algún accesorio más :por ejemplo sonido, algún tipo de luz, sensores ultrasonidos , etc

 

2016-03-27_23h10_21

Por cierto  el código completo esta disponible en su pagina oficial de Github

 

Fuente  aqui  

Coche RC Autonomo basado en Rasberry Pi y Arduino


Este proyecto desarrollado por   Zeng Wang  constituye  una versión reducida de un  sistema de auto-conducción ( eso si usando un coche de RC) con una Raspberry Pi 2 Model B – Placa base (ARM Quad-Core 900 MHz, 1 GB RAM, 4 x USB, HDMI, RJ-45)
, un Arduino ,y  un ordenador exterior con software de código abierto.

El sistema utiliza tanto una Raspberry Pi con la cámara incorporada  oficial  como un sensor ultrasónico como entradas, enviando la informacion a un ordenador  que recibe el video  y se encarga del procesamiento en tiempo real del video capturado por la raspberry Pi mediante  reconocimiento de objetos (señal de stop y semáforos) y medición de distancia  ordenando las señales correspondientes  de la dirección mediante una placa Arduino para el control del coche de RC.

Dos programas ejecutándose en la Raspberry Pi permiten gestionar la información que recibe y la transmiten junto al vídeo de baja resolución (320 x 240) que capta la cámara a otro ordenador vía WiFi .A su vez el mando que controla el coche teledirigido efectivamente sigue dirigiéndolo, pero lo hace a través de las órdenes que le pasa ese ordenador vía USB mediante una placa Arduino.

El código fuente esta disponible en git hub 

El resultado, como puede verse en el vídeo, es espectacular .

 

 

 

El objetivo del autor Wang en efecto era modificar un coche RC  para que fuese capaz de  manejar tres tareas: auto-conducción en la pista, la señal de detención  ,la detección semáforo, y evitar colisiones frontales.

El sistema construido  consta de tres subsistemas:

  • Unidad de entrada (cámara, el sensor de ultrasonidos)
  • Unidad de procesamiento (ordenador) y
  • Unidad de control del coche RC.

Unidad de entrada

Una placa  Raspberry Pi 2 Model B – Placa base (ARM Quad-Core 900 MHz, 1 GB RAM, 4 x USB, HDMI, RJ-45) al que se conecta un módulo de cámara pi y un sensor ultrasónico-HC SR04 se utiliza para recoger datos de entrada. Dos programas de cliente se ejecutan en Raspberry Pi para el streaming de vídeo en color y datos de los sensores ultrasónicos a la computadora a través de conexión Wi-Fi local.Con el fin de conseguir una baja latencia de streaming de vídeo, el vídeo se escala hasta QVGA (320 × 240) resolución.

Unidad de procesamiento

La unidad de procesamiento (ordenador) se encarga de múltiples tareas: recibir datos de Raspberry Pi, el entrenamiento de la red neural red y la predicción (dirección), la detección de objetos (señal de stop y semáforos), medición de distancia (visión monocular), y el envío de instrucciones via Arduino a través de conexión USB .

Servidor TCP
Un programa de servidor TCP multihilo se ejecuta en el ordenador para recibir cuadros de imagen por streaming y datos ultrasónicos de la Raspberry Pi. Los cuadros de imagen se convierten a escala de grises y se descodifican en matrices numpy.

Red Neuronal
Una ventaja de usar la red neuronal es que una vez que la red ha aprendido, sólo necesita cargar parámetros formados después, y por tanto, la predicción puede ser muy rápida. Sólo la mitad inferior de la imagen de entrada se utiliza para fines de aprendizaje y de predicción. Hay 38.400 (320 × 120) nodos en la capa de entrada y 32 nodos en la capa oculta. El número de nodos en la capa oculta se elige bastante arbitrario.

Hay cuatro nodos en la capa de salida, donde cada nodo corresponde a las instrucciones de control de dirección: izquierda, derecha, adelante y atrás respectivamente (aunque inversa no se utiliza  Wang la ha incluido en la capa de salida).

mlp_half_32-2

A continuación se muestra el proceso de recolección de datos de entrenamiento.Primero cada cuadro se recorta y se convierte en una matriz numpy. Entonces la imagen de tren está emparejado con la etiqueta de tren (entrada humana). Por último, todos los datos y etiquetas de imagen emparejados se guardan en un archivo NPZ. La red neuronal está entrenada en el uso de OpenCV  usando el  método de propagación de vuelta. Una vez que la formación se lleva a cabo, los pesos se guardan en un archivo xml. Para generar predicciones, la misma red neuronal se construye y se carga con el archivo xml capacitado.

collect_train_data

Detección de Objetos
Para este proyecto Wang adaptó el enfoque basado en la forma utilizando clasificadores en cascada Haar basados ​​en características para la detección de objetos. Desde cada objeto se requiere su propio clasificador y sigue el mismo proceso de formación y detección, asi que en este proyecto sólo se centra en señal de stop y la detección del semáforo.

OpenCV proporciona un entrenador, así como detector. Las muestras positivas (contener objeto de destino) fueron adquiridos utilizando un smartphone , y se recortan para que solo el objeto deseado sea visible. Las muestras negativas (sin objeto de destino), por otro lado, se recogieron al azar. En particular, para el semáforo  muestras positivas contienen igual número de semáforos en rojo que semáforos en verde. El mismo conjunto de datos de muestras negativas se utilizan tanto para la señal de stop como para  la formación del semáforo. A continuación se muestran algunas muestras positivas y negativas utilizadas en este proyecto.

pos_neg_samples

sample_tabel

Para reconocer diferentes estados del semáforo (rojo, verde), se necesita un poco de procesamiento de imágenes más allá de la detección.

El diagrama de flujo a continuación resume el proceso de reconocimiento semáforo.

brightest_spot

En primer lugar, entrenado el clasificador en  cascada se utiliza éste para detectar un semáforo. El cuadro delimitador es considerada como una región de interés (ROI). En segundo lugar, la falta de definición de Gauss se aplica dentro de la ROI para reducir ruidos. En tercer lugar, encontrar el punto más brillante en el retorno de la inversión. Por último, los estados rojos o verdes se determinan basándose simplemente en la posición del punto más brillante en el retorno de la inversión.

Distancia de medida
Raspberry Pi sólo puede soportar un módulo de cámara de un pi. El uso de dos cámaras web USB traerá peso extra para el coche RC y también parece poco práctico.Por lo tanto, se elige el método visión monocular.

Este proyecto adaptó un modelo de geometría de detectar la distancia a un objeto utilizando el método de la visión monocular propuesto por Chu, Ji, Guo, Li y Wang (2004).

distante

P es un punto en el objeto de destino; d es la distancia desde el centro óptico hasta el punto P. En base a la geometría de la relación anterior, la fórmula (1) muestra cómo calcular la distancia d. En la fórmula (1), f es la longitud focal de la cámara; ∂ es el ángulo de inclinación de la cámara; h es la altura del centro óptico; (x0, y0) se refiere al punto de plano de la imagen y el eje óptico intersección; (x, y) se refiere a la proyección del punto P en el plano de la imagen. Supongamos O1 (u0, v0) es la cámara de coordenadas del punto de eje óptico y el plano de la imagen de intersección, también supongamos que la dimensión física de un píxel correspondiente al eje X y el eje Y en el plano de la imagen son dx y dy. Entonces:
distance_measure
v es la cámara de coordenadas en el eje y, y se puede devolver en el proceso de detección de objetos. Todos los demás parámetros son parámetros intrínsecos de la cámara que se pueden recuperar de la matriz de la cámara.

OpenCV proporciona funciones para calibración de la cámara. Matriz de la cámara para la cámara de 5MP pi se devuelve después de la calibración. Idealmente, a_x y a_y tienen el mismo valor. Varianza de estos dos valores se traducirá en píxeles no cuadrados en la imagen. La siguiente matriz indica que la lente de longitud focal fija en cámara pi ofrece un razonablemente buen resultado en el manejo de la distorsión de aspecto. Aquí es un artículo interesante discutir la distancia focal de la cámara pi con la acción de la lente y su equivalente de cámara de 35mm.
pi_cam_matrixLa matriz devuelve valores en píxeles y h se mide en centímetros. Mediante la aplicación de la fórmula (3), la distancia física d se calcula en centímetros.

Unidad RC Car Control

El coche RC utilizada en este proyecto tiene un controlador tipo de interruptor de encendido / apagado. Cuando se pulsa un botón, la resistencia entre el contacto pasador y el suelo chip de referencia es cero. Por lo tanto, una placa Arduino se utiliza para simular las acciones sobre el pulsador. Cuatro pines de Arduino se eligen para conectar cuatro clavijas de chips en el controlador, que corresponde a adelante, atrás, izquierda y derecha, respectivamente, acciones. Pines de Arduino envian señales baja indicando a tierra los pines de chips del controlador; Por otro lado el envío de señal de alta indica la resistencia entre los pines de chips y suelo permanecen sin cambios. El Arduino se conecta al ordenador a través de USB. Las salidas de computadora comandos para Arduino utilizando interfaz serie, y luego el Arduino lee los comandos y escribe señales de bajo o alto, simulando acciones de botón de prensa para conducir el coche RC.

Resultados

La predicción de las muestras de prueba devuelve una precisión de 85% en comparación con la precisión de 96% de que las muestras de entrenamiento devoluciones. En la situación de conducción real, predicciones se generan cerca de 10 veces por segundo (velocidad de transmisión de aproximadamente 10 fotogramas / s).

Características Haar por naturaleza son la rotación sensible. En este proyecto, sin embargo, la rotación no es una preocupación ya que tanto la señal de stop y el semáforo son objetos fijos, que es también un caso general en el entorno del mundo real.

drive_test01drive_test02

Para distancia aspecto medición, el sensor de ultrasonidos sólo se utiliza para determinar la distancia a un obstáculo delante del coche RC y proporciona resultados exactos cuando se toma la detección de ángulo adecuado y estado de la superficie en las consideraciones. Por otro lado, la cámara Pi ofrece “suficientemente buenos” resultados de la medición. De hecho, siempre y cuando sabemos que el número correspondiente a la distancia real, sabemos cuándo dejar el coche RC. Los resultados experimentales de detección a distancia usando la cámara pi se muestran a continuación:
camera_measure2

En este proyecto, la exactitud de la medición de la distancia utilizando el enfoque de visión monocular podría estar influenciada por los siguientes factores: (1) errores en la medición de los valores reales, (2) objeto de delimitación variaciones de caja en el proceso de detección, (3) errores en el proceso de calibración de la cámara, (4) relación no lineal entre la distancia y la cámara de coordenadas: la mayor distancia del, más rápido cambio de la cámara de coordenadas, por lo tanto cuanto mayor sea el error.

En general, el coche de RC podría navegar con éxito en la pista con la capacidad de evitar la colisión frontal, y responder a la señal de stop y semáforos en consecuencia.

Segun Wang ,el proceso de entrenamiento fue relativamente sencillo debido a la sencillez del modelo de carretera utilizada, y a eso se le sumaba la detección de objetos gestionada por la plataforma OpenCV (Open Source Computer Vision) que entre otras cosas también permitía calibrar la cámara.

 

Es sin duda  un proyecto apasionante y sorprendente el que ha realizado  Zheng Wang  demostrando  una vez hasta donde  puede llegar  la capacidad de procesamiento  actual  presentes en dispositivos tan reducidos y modestos como lo constituye la gama  de la Raspberry Pi 2 Model B – Placa base (ARM Quad-Core 900 MHz, 1 GB RAM, 4 x USB, HDMI, RJ-45)

Mas  información en la web del autor

Envio de correo SMTP desde Netduino


Todos sabemos, que Micro Framework no puede tener todas las características de .NET Framework completo. Una cosa que  faltaba es SmtpClient clase que permita el envío de mensajes de correo electrónico utilizandoSimple Mail Transfer Protocol (SMTP). Si nos fijamos en la especificación SMTP encontrará protocolo comuinication muy fácil – es sólo comandos de texto. Comando no, la respuesta Atrás – eso es todo.

Asi  es de fácil puede ser el envío de e-mails de .NET Micro Framework pero  no lamntablemente esta clase no esta disponible para , Net Micro Framework 

 utilizando (SmtpClient smtp = new SmtpClient ("smtp.hostname.net", 25))
 {
     // Enviar mensaje
     smtp.Send ("[email protected]",
               "[email protected]",
               "Buenas noticias",
               "¿Cómo te Foo?");
 }

Esto le  trajo  la idea a Pavel Bánský  de escribir  su propia implementación de la clase SmtpClient para .NET Micro Framework   que ademas  ha decididoser lo más compatible posible con la versión de “escritorio” de System.Net.Mail.SmtpClient clase.

1920px-par_avion_air_mail
Par avion air mail” by Kristoferb at English Wikipedia. Licensed under CC BY-SA 3.0 via Commons.

 

 

 

Bansky.SPOT.Mail biblioteca de clases

Enviar sencilla correo electrónico mediante SMTP es muy fácil; PERO. Hoy en día la mayor parte del servidor SMTP requiere autenticación. Esto significa, que SmtpClient sin autenticación sería un poco inútil.

En el caso de usar el servidor de correo de terra

SMTP: smtp.terra.com

Puerto 587 o 465 (SSL)

Pero  atención   , no podra usar SSL, por  lo que no olvide  apuntar el puerto 587

Y aquí comienza la diversión. Autenticación SMTP necesita Base64 nombre de usuario y la contraseña codificada. Damned, Base64 no es compatible con Micro Framework. Por lo tanto, la primera tarea es obtener Base64 clase de codificación / decodificación. Una vez que usted pueda codificar datos en Base64, puede codificar los datos de los archivos adjuntos de correo electrónico también. Vamos a implementar System.Net.Mail.Attachment clase. Más funcionalidad necesita el manejo de excepciones más compleja. Ok, agreguela clase  System.Net.Mail.SmtpException .

Después de unos días te despiertas y ves, que ha terminado con la biblioteca de clases completa para el correo electrónico. Eso es cómo se  creo biblioteca de clases Bansky.SPOT.Mail 

Base 64, Autenticación y error en Micro Framework

Cuando el servidor SMTP requiere autenticación, el cliente de sesión de inicio con el comando EHLO domain.com.Servidor responde con métodos compatibles de autenticación. Simplemente dicho, los métodos de las credenciales de codificación. La mayoría de los servidores SMTP soporta método SENCILLOS o entrada o ambos; si no, SmtpClientva a terminar con una excepción. Hay otros métodos de autenticación como CRAM-MD5 y CRAM-SHA1.

Información de autenticación para el método SENCILLOS es esta cadena “usernamepassword” codificado en Base64. El problema es que Micro Framework versión 2.5 (y menos) interpreta “” como un fin de la cadena. Esto significa que la cadena de autenticación SENCILLOS se interpreta como una cadena vacía. Caracteres  después de  “” se ignoran pero esto se puede. En primer lugar debe conviertir  en  serie de “contraseña de usuario” en la matriz de bytes y luego reemplazar los espacios adecuados con el byte 0x00. Tal matriz de bytes es la entrada para el método Base64.Encode ().

Es importante decir que el núcleo de la clase Base 64 se basa en Base64Encoder clase de Timm Martin  y se  he añadido los métodos para dividir los datos codificados en líneas de 76 bytes como es requerido por MIME especificación.

Siguiente código muestra cómo configurar las credenciales de autenticación a clase SmtpClient. Método de autenticación será elegido automáticamente en función de las capacidades del servidor.

 utilizando (SmtpClient smtp = new SmtpClient ("smtp.hostname.net", 25))
 {
     // Crear un mensaje
     MailMessage mensaje = new MailMessage ("[email protected]",
                                           "[email protected]",
                                           "Buenas noticias",
                                           "¿Cómo te Foo?");

     // Authenicate al servidor
     smtp.Authenticate = true;
     smtp.Username = "UserLogin";
     smtp.Password = "userpassword";

     // Enviar mensaje
     smtp.Send (mensaje);
 }

Archivos adjuntos de correo electrónico

Además de los mensajes HTML con formato, la implementación MailMessage soporta archivos adjuntos. Archivo adjunto de e-mail puede ser cualquier dato binario, que se procesan utilizando la codificación Base64 y agregados en mensaje MIME multiparte. Ejemplo de mensaje con archivo adjunto está por debajo.

ADVERTENCIA: codificación de datos binarios en base64 en .NET Micro Framework puede ser extremadamente tiempo y consumo de recursos. Esto significa, que el mayor de los datos es, más tiempo se necesita para procesarla; y si se dice  “más tiempo”, es porque  es  realmente mucho tiempo. Por lo tanto, tener cuidado y no se sorprenda.

 MailMessage mensaje = new MailMessage ();
 // Establecer el nombre del remitente y dirección
 message.From = new MailAddress ("[email protected]", "Foo Bar");

 // Destinatarios Set
 message.To.Add (nueva MailAddress ("[email protected]", "John Doe"));
 message.Cc.Add (nueva MailAddress ("[email protected]"));

 message.Subject = "Hola Mundo";
 message.Body = "de ahora en adelante usted puede enviar mensajes de correo electrónico desde <b> .NET Micro Framework </ b>.";
 // Cuerpo Formato como HTML
 message.IsBodyHtml = true;

 // Crear nuevo adjunto y definir su nombre
 Accesorio = nuevo Adjunto ("Snwoflake.gif");        
 attachment.ContentType = "image / gif";
 attachment.TransferEncoding = TransferEncoding.Base64;
 // Contenidos adjuntos
 attachment.Content = Base64.Encode (Resources.GetBytes (
                                     Resources.BinaryResources.Snowflake_gif),
                                     true);

 // Añadir adjunto al mensaje
 message.Attachments.Add (archivo adjunto);

 // Crear instancia SMTP nueva
 SmtpClient smtp = new SmtpClient ("smtp.contoso.com", 25);
 probar
 {
     // Authenicate al servidor
     smtp.Authenticate = true;
     smtp.Username = "UserLogin";
     smtp.Password = "userpassword";

     // Enviar mensaje
     smtp.Send (mensaje);
 }
 capturas (SmtpException e)
 {
     // El manejo de excepciones aquí
     Debug.Print (e.Message);
     Debug.Print ("Código de error:" + e.ErrorCode.ToString ());
 }
 finalmente
 {
     smtp.Dispose ();
 }

Cabeceras adicionales

Cada mensaje de correo contiene cabecera, que especifica la información como la fecha en que se creó el mensaje, el nombre del remitente, etc. Si usted quiere poner información adicional en la cabecera se puede utilizar la propiedadencabezados. Consulte el siguiente ejemplo.

 MailMessage mensaje = new MailMessage ("[email protected]",
                                       "[email protected]",
                                       "Buenas noticias",
                                       "¿Cómo te Foo?");

 message.Headers = "X-Priority: 1 
  ";
 message.Headers + = "X-Microsoft Mail-Prioridad: Alta 
  ";
 message.Headers + = "X-Mailer: Micro Framework mail del remitente 
  ";

Manejo de excepciones

Además excepciones estándar como ArgumentNullException y ArgumentOutOfRangeException, también haySmtpException lanzada por Enviar método de SmtpClient. SmtpException en marco completo contiene propiedadStatusCode, que describe el estado en que se produjo la excepción. Desde mi Enviar método no es tan rico, he reemplazado StatusCode con ErrorCode, que describe la razón de la excepción. La enumeración SmtpErrorCodecontiene valores como BarResponse, AuthFailed, connectionFailed y así sucesivamente.

Demostración y Descarga

Biblioteca completa con las fuentes, documentación y aplicación de la muestra están disponibles para su descarga.Biblioteca fue probado en emulador y Maestro GHI Embedded módulo. Todo el código    el autor  ha  movido el   software al repositorio GitHub.

 

 

 

Fuente