Semana 13: Unidad 6¶
Propósitos de aprendizaje¶
En esta unidad 6 abordaremos la última parte del curso. Vamos a utilizar todo lo aprendido hasta ahora para aprender cómo integrar sensores y actuadores a herramientas de software para la construcción de aplicaciones interactivas.
Código de honor¶
Para realizar las actividades y el RETO de evaluación se espera que hagas lo siguiente:
- Colabora con tus compañeros cuando así se indique.
- Trabaja de manera individual cuando la actividad así te lo proponga.
- Usa solo la documentación oficial del framework del controlador, .NET de Microsoft y Unity
- NO DEBES utilizar sitios en Internet con soluciones o ideas para abordar el problema.
- NO DEBES hacer uso de foros.
- ¿Entonces qué hacer si no me funciona algo? Te propongo que experimentes, crea hipótesis, experimenta de nuevo, observa y concluye.
- NO OLVIDES, este curso se trata de pensar y experimentar NO de BUSCAR soluciones en Internet.
- VAMOS A TENER SESIONES sincrónicas donde podrás trabajar y resolver dudas en tiempo real con el docente.
Trayecto de acciones, tiempos y formas de trabajo¶
Actividad 1¶
- Fecha: septiembre 28 de 2020
- Descripción: vamos a introducir la unidad.
- Recursos: ingresa a Teams
- Duración de la actividad: 1 hora , 20 minutos.
- Forma de trabajo: grupal
Reto de la Unidad anterior sin hilos¶
Te dejo una propuesta de solución al reto de la unidad anterior. Primero sin el hilo que imprime el contador y luego con ese hilo.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | using System;
using System.IO.Ports;
namespace sem11Reto1
{
class Program
{
private static SerialPort _serialPort = new SerialPort();
private static readonly byte[] q_commnad = new byte[] { 0x04, 0xFF, 0x21, 0x19, 0x95 };
private static readonly byte[] w_commnad = new byte[] { 0x05, 0x00, 0x24, 0x00, 0x25, 0x29 };
private static readonly byte[] e_commnad = new byte[] { 0x05, 0x00, 0x2F, 0x1E, 0x72, 0x34 };
private static readonly byte[] r_commnad = new byte[] { 0x06, 0x00, 0x22, 0x31, 0x80, 0xE1, 0x96 };
private static readonly byte[] t_commnad = new byte[] { 0x05, 0x00, 0x28, 0x05, 0x28, 0xD7 };
private static readonly byte[] y_commnad = new byte[] { 0x05, 0x00, 0x25, 0x00, 0xFD, 0x30 };
private static byte[] buffer = new byte[32];
static void Main(string[] args)
{
// Allow the user to set the appropriate properties.
_serialPort.PortName = "COM4";
_serialPort.BaudRate = 57600;
_serialPort.DtrEnable = true;
_serialPort.Open();
while (true)
{
Console.WriteLine();
Console.WriteLine("Commands available: Q: 0x21, W: 0x24, E: 0x2F, R: 0x22, T: 0x28, Y: 0x25");
switch (Console.ReadKey(true).Key)
{
case ConsoleKey.Q:
sendCommand(q_commnad);
readData();
break;
case ConsoleKey.W:
sendCommand(w_commnad);
readData();
break;
case ConsoleKey.E:
sendCommand(e_commnad);
readData();
break;
case ConsoleKey.R:
sendCommand(r_commnad);
readData();
break;
case ConsoleKey.T:
sendCommand(t_commnad);
readData();
break;
case ConsoleKey.Y:
sendCommand(y_commnad);
readData();
break;
default:
break;
}
}
}
private static void sendCommand(byte[] data)
{
Console.Write("Send this packet: ");
for(int i = 0; i < data.Length; i++)
{
Console.Write("{0:X2}",data[i]);
Console.Write(' ');
}
Console.WriteLine();
_serialPort.Write(data, 0, data.Length);
}
private static void readData()
{
// 1. Este llamado bloque completamente el hilo
// esperando a que lleguen datos por el puerto serial
while (_serialPort.BytesToRead == 0) ;
// 2. Leo el primer byte que me dice la longitud
_serialPort.Read(buffer, 0, 1);
// 3. Espero el resto de datos
while (_serialPort.BytesToRead < buffer[0]) ;
// 4. Leo los datos
_serialPort.Read(buffer, 1, buffer[0]);
// 5. Verifica el checksum
bool checksumOK = verifyChecksum(buffer);
Console.Write("Packet received: ");
for(int i = 0; i < (buffer[0] + 1); i++)
{
Console.Write("{0:X2}", buffer[i]);
Console.Write(' ');
}
if(checksumOK == false)
{
Console.WriteLine(" Checksum Fails");
}
else
{
Console.WriteLine();
}
}
private static bool verifyChecksum(byte[] packet)
{
bool checksumOK = false;
byte ucI, ucJ;
int uiCrcValue = 0x0000FFFF;
int len = packet[0] + 1;
for (ucI = 0; ucI < (len - 2); ucI++)
{
uiCrcValue = uiCrcValue ^ packet[ucI];
for (ucJ = 0; ucJ < 8; ucJ++)
{
if ((uiCrcValue & 0x00000001) == 0x00000001)
{
uiCrcValue = (uiCrcValue >> 1) ^ 0x00008408;
}
else
{
uiCrcValue = (uiCrcValue >> 1);
}
}
}
int LSBCkecksum = uiCrcValue & 0x000000FF;
int MSBCkecksum = (uiCrcValue & 0x0000FF00) >> 8;
if ((packet[len - 2] == LSBCkecksum) && (packet[len - 1] == MSBCkecksum)) checksumOK = true;
return checksumOK;
}
}
}
|
Tenga presente que este código no hace ninguna verificación de errores de entrada/salida, por ejemplo:
- ¿Qué pasa si el sensor se desconecta?
- ¿Qué pasa si el sensor se desconecta en medio de una transmisión
- y no llegan los datos?
Ahora adicionamos el hilo que muestra el contador cada 100 ms
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | using System;
using System.IO.Ports;
using System.Threading;
namespace sem11Reto1
{
class Program
{
private static SerialPort _serialPort = new SerialPort();
private static readonly byte[] q_commnad = new byte[] { 0x04, 0xFF, 0x21, 0x19, 0x95 };
private static readonly byte[] w_commnad = new byte[] { 0x05, 0x00, 0x24, 0x00, 0x25, 0x29 };
private static readonly byte[] e_commnad = new byte[] { 0x05, 0x00, 0x2F, 0x1E, 0x72, 0x34 };
private static readonly byte[] r_commnad = new byte[] { 0x06, 0x00, 0x22, 0x31, 0x80, 0xE1, 0x96 };
private static readonly byte[] t_commnad = new byte[] { 0x05, 0x00, 0x28, 0x05, 0x28, 0xD7 };
private static readonly byte[] y_commnad = new byte[] { 0x05, 0x00, 0x25, 0x00, 0xFD, 0x30 };
private static byte[] buffer = new byte[32];
private static bool running = true;
private static void counterCode()
{
int counter = 0;
while (running)
{
Thread.Sleep(1000);
Console.WriteLine(counter);
counter = (counter + 1) % 100;
}
}
static void Main(string[] args)
{
Thread counterThread = new Thread(counterCode);
counterThread.Start();
// Allow the user to set the appropriate properties.
_serialPort.PortName = "COM4";
_serialPort.BaudRate = 57600;
_serialPort.DtrEnable = true;
_serialPort.Open();
while (running)
{
Console.WriteLine();
Console.WriteLine("Commands available: Q: 0x21, W: 0x24, E: 0x2F, R: 0x22, T: 0x28, Y: 0x25 X:exit");
switch (Console.ReadKey(true).Key)
{
case ConsoleKey.Q:
sendCommand(q_commnad);
readData();
break;
case ConsoleKey.W:
sendCommand(w_commnad);
readData();
break;
case ConsoleKey.E:
sendCommand(e_commnad);
readData();
break;
case ConsoleKey.R:
sendCommand(r_commnad);
readData();
break;
case ConsoleKey.T:
sendCommand(t_commnad);
readData();
break;
case ConsoleKey.Y:
sendCommand(y_commnad);
readData();
break;
case ConsoleKey.X:
running = false;
break;
default:
break;
}
}
counterThread.Join();
}
private static void sendCommand(byte[] data)
{
Console.Write("Send this packet: ");
for(int i = 0; i < data.Length; i++)
{
Console.Write("{0:X2}",data[i]);
Console.Write(' ');
}
Console.WriteLine();
_serialPort.Write(data, 0, data.Length);
}
private static void readData()
{
// 1. Este llamado bloque completamente el hilo
// esperando a que lleguen datos por el puerto serial
while (_serialPort.BytesToRead == 0) ;
// 2. Leo el primer byte que me dice la longitud
_serialPort.Read(buffer, 0, 1);
// 3. Espero el resto de datos
while (_serialPort.BytesToRead < buffer[0]) ;
// 4. Leo los datos
_serialPort.Read(buffer, 1, buffer[0]);
// 5. Verifica el checksum
bool checksumOK = verifyChecksum(buffer);
Console.Write("Packet received: ");
for(int i = 0; i < (buffer[0] + 1); i++)
{
Console.Write("{0:X2}", buffer[i]);
Console.Write(' ');
}
if(checksumOK == false)
{
Console.WriteLine(" Checksum Fails");
}
else
{
Console.WriteLine();
}
}
private static bool verifyChecksum(byte[] packet)
{
bool checksumOK = false;
byte ucI, ucJ;
int uiCrcValue = 0x0000FFFF;
int len = packet[0] + 1;
for (ucI = 0; ucI < (len - 2); ucI++)
{
uiCrcValue = uiCrcValue ^ packet[ucI];
for (ucJ = 0; ucJ < 8; ucJ++)
{
if ((uiCrcValue & 0x00000001) == 0x00000001)
{
uiCrcValue = (uiCrcValue >> 1) ^ 0x00008408;
}
else
{
uiCrcValue = (uiCrcValue >> 1);
}
}
}
int LSBCkecksum = uiCrcValue & 0x000000FF;
int MSBCkecksum = (uiCrcValue & 0x0000FF00) >> 8;
if ((packet[len - 2] == LSBCkecksum) && (packet[len - 1] == MSBCkecksum)) checksumOK = true;
return checksumOK;
}
}
}
|
Actividad 2¶
- Fecha: septiembre 28 a septiembre 30 de 2020
- Descripción: realiza los ejercicios propuestos.
- Recursos: mira los ejercicios abajo.
- Duración de la actividad: 5 horas.
- Forma de trabajo: individual
Ejercicio 1¶
Al final de la guía te dejo un MINI-RETO. Este consiste en estudiar a fondo el código fuente del plugin. Es un reto grande porque posiblemente tengas que recordar algunas de tus cursos anteriores de programación en el programa. Es por ello que el mini-reto requiere que repases y estudies algunas cosas nuevas.
Una vez hagas el paso anterior:
- Crea un proyecto nuevo en Unity.
- Configura el soporte para el puerto serial tal como lo viste en la guía.
- OJO, no instales el paquete Ardity. SI YA LO HICISTE, vuelva a comenzar.
- Ahora toma únicamente LOS SCRIPTS de Ardity necesarios (SOLO LOS NECESARIOS) para hacer que la aplicación de la guía funcione de nuevo.
Actividad 3¶
- Fecha: septiembre 30 de 2020
- Descripción: realiza los ejercicios propuestos con soporte del docente para resolver dudas en tiempo real.
- Recursos: ingresa a Teams
- Duración de la actividad: 1 hora , 20 minutos.
- Forma de trabajo: grupal
En esta sesión vamos a terminar el material de esta semana y a resolver dudas de la actividad final de análisis de Ardity.