Semana 12¶
Retos de la semana pasada: RETO 1¶
El primer reto de la semana pasada podría quedar así:
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:
- Se desconectó el sensor
- Se desconectó el sensor en medio de una transmisión y no llegan los datos completos.
Retos de la semana pasada: RETO 2¶
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;
}
}
}
|
Integración con Unity¶
Esta semana vamos a abordar la integración de sensores y actuadores o un motor como Unity. Para ellos vamos a tomar como referencia un plugin para Unity llamado Ardity.
La guía de trabajo se encuentra aquí
Ejercicio: RETO (está al final de la guía de trabajo)¶
Este reto es muy importante y consisten en estudiar a fondo el código fuente del plugin. Es un reto grande porque posiblemente usted no recuerde algunas cosas de C# o nunca las trabajó en un curso previo. Es por ello que el reto requiere que repase y estudie algunas cosas nuevas.
Una vez haga el paso anterior:
- Cree un proyecto nuevo en Unity.
- Configure el soporte para el puerto serial tal como lo realizó en la guía.
- OJO, no instale el paquete Ardity. SI YA LO HIZO, vuelva a comenzar.
- Ahora tome únicamente LOS SCRIPTS de Ardity necesarios (SOLO LOS NECESARIOS) para hacer que la aplicación de la guía funcione de nuevo.