El código fuente del programa para la PC & lt; code class = & quot; cpp & quot; & gt; #include & lt; stdlib.h & gt; #include & lt; sys / time.h & gt; #include & lt; time.h & gt; #include & lt; stdio.h & gt; #include & lt; string.h & gt; #include & lt; libusb-1.0 / libusb.h & gt; #include & lt; iostream & gt; #include & lt; cadena & gt; #include & lt; vectorial & gt; #define MAGIC 0x41444C49 línea estática uint16_t swapshort (uint16_t v) {return (v & gt; & gt; 8) | (v & lt; & lt; 8); } Escala flotador = 1,0; typedef struct {uint32_t magia; uint8_t Pad1 [3]; formato uint8_t; char nombre [8]; empresa char [8]; uint16_t contar; frameno uint16_t; frameCount uint16_t; escáner uint8_t; pad2 uint8_t; } ((Pic)) ilda_hdr __attribute __; #define #define 0x40 Vacia Ultima 0x80 typedef struct {int16_t x; int16_t y; z int16_t; Estado uint8_t; de color uint8_t; } ((Pic)) icoord3d __attribute __; typedef struct {coord3d int16_t x; int16_t y; z int16_t; Estado uint8_t; coord3d (int16_t x, int16_t y, int16_t z, estado uint8_t): x (x), y (y), z (z), estado (estado) {}} coord3d; typedef struct {std :: vector & lt; coord3d & gt; puntos; posición int; } Marco; rframe marco; subpos int; int divisor = 1; int loadildahdr (FILE * ild, ilda_hdr & amp; hdr) {if (fread (& amp; hdr, sizeof (HDR), 1, ILD) = 1!) {std :: cerr & lt; & lt; & Quot; Error al leer encabezado & quot; & Lt; & lt; std :: endl; devuelve -1; } Si (hdr.magic = MAGIA!) {Std :: cerr & lt; & lt; & Quot; la magia no válida & quot; & Lt; & lt; std :: endl; devuelve -1; } Si (hdr.format = 0!) {Fprintf (stderr, & quot; tipo de sección no admitida% d n \ & quot;, hdr.format); devuelve -1; Hdr.count} = swapshort (hdr.count); hdr.frameno = swapshort (hdr.frameno); hdr.framecount = swapshort (hdr.framecount); } Int loadild (std const :: string & amp; archivo, marco & amp; fotograma) {int i; ARCHIVO * ild = fopen (file.c_str (), & quot; rb & quot;); si (ILD!) {std :: cerr & lt; & lt; & Quot; No se puede abrir & quot; & Lt; & lt; archivo & lt; & lt; std :: endl; devuelve -1; } Hdr Ilda_hdr; loadildahdr (ILD, hdr); for (int f = 0; f & lt; hdr.framecount; f ++) {std :: cout & lt; & lt; & Quot; Frame & quot; & Lt; & lt; hdr.frameno & lt; & lt; & Quot; de & quot; & Lt; & lt; hdr.framecount & lt; & lt; & Quot; & Quot; & Lt; & lt; hdr.count & lt; & lt; & Quot; puntos & quot; & Lt; & lt; std :: endl; icoord3d * tmp = (icoord3d *) calloc (hdr.count, sizeof (icoord3d)); si (fread (tmp, sizeof (icoord3d), hdr.count, ILD) = hdr.count!) {std :: cerr & lt; & lt; & Quot; Error al marco de lectura & quot; & Lt; & lt; std :: endl; devuelve -1; } For (i = 0; i & lt; hdr.count; i ++) {punto coord3d (swapshort (tmp [i] .x), swapshort (tmp [i] .y), swapshort (tmp [i] .z), tmp [i] .state); frame.points.push_back (punto); } Gratuito (tmp); loadildahdr (ILD, hdr); } Fclose (ILD); return 0; } Breve outBuffer [128]; proceso de int () {frame * frame = & amp; rframe; corta * sx = & amp; outBuffer [0]; corta * sy = & amp; outBuffer [1]; for (int frm = 0; frm & lt; 64; frm ++) {struct coord3d * c = & amp; marco & gt; puntos [marco & gt; posición]; * Sx = 4095 - (2047 + (2,048 * c- & gt; x / 32768)) * escala; * Sy = (2.047 + (2,048 * c- & gt; a / 32768)) * escala; si (c- & gt; & amp Estado; BLANCO) {* sx | = 1 & lt; & lt; 15; } Else {* sx & amp; = ~ (1 & lt; & lt; 15); } + Sx = 2; sy + = 2; subpos ++; if (subpos == divisor) {subpos = 0; si (c- & gt; & amp Estado; APELLIDO) marco & gt; posición = 0; otro marco & gt; posición = (marco & gt; la posición + 1)% marco & gt; points.size (); }} Return 0; } Int main (int argc, char ** argv) {libusb_device_handle * dev; libusb_context * ctx = NULL; int ret, real; ret = libusb_init (& amp; CTX); si (r & lt; 0) {fprintf (stderr, & quot; No se pudo inicializar libusb \ n & quot;); volver EXIT_FAILURE; } Libusb_set_debug (ctx, 3); dev = libusb_open_device_with_vid_pid (CTX, 0x1cbe, 0x0003); si (dev == NULL) {fprintf (stderr, & quot; No se puede abrir el dispositivo \ n & quot;); volver EXIT_FAILURE; } Printf demás (& quot; Dispositivo abrieron \ n & quot;); si (libusb_kernel_driver_active (dev, 0) == 1) {fprintf (stderr, & quot; controlador Kernel \ n & quot activa;); libusb_detach_kernel_driver (dev, 0); } Ret = libusb_claim_interface (dev, 0); si (r & lt; 0) {fprintf (stderr, & quot; no podía reclamar interfaz \ n & quot;); volver EXIT_FAILURE; } // Para mantener nuestros ts timespec struct frecuencia de muestreo; ts.tv_sec = 0; ts.tv_nsec = 2000000; memset (& amp; rframe, 0, sizeof (marco)); si (loadild (argv [1], rframe) & lt; 0) {fprintf (stderr, & quot; No se ha podido cargar ILDA \ n & quot;); volver EXIT_FAILURE; } While (1) {process (); if (nanosleep (& amp; ts, NULL) = 0!) fprintf (stderr, & quot; nanosleep falló & quot;); ret = libusb_bulk_transfer (dev, (1 | LIBUSB_ENDPOINT_OUT), (unsigned char *) & amp; outBuffer, 256, & amp; real, 0); si (RET = 0 || real = 256!) fprintf (stderr, & quot; Error de escritura \ n & quot;); } Libusb_release_interface (dev, 0); libusb_close (dev); libusb_exit (CTX); return 0; } & Lt; / Código & gt; pre>
Las funciones de la main () code> pre> usando nanosleep también gobernado por la frecuencia con la que los nuevos datos se envía al microcontrolador.
El código fuente completo del firmware del controlador están disponibles en GitHub .
Planes para el futuro h4> Está previsto terminar estas cosas todavía a un estado similar al arpa láser pensado originalmente. Para este propósito único en lugar de dos espejos, ya que el haz láser mueve a lo largo un solo eje. El principio de funcionamiento del arpa es que el controlador se enciende y se apaga rayo láser en determinados momentos se crean con láser "Teclado" en el aire. Artista, el bloqueo de la mano en el guante de reflexión rayo láser brillante activa el elemento fotosensible en la base del "arpa". Desde el microcontrolador sabe en qué momento qué parte del teclado, se "pintó" que puede determinar cuál de las vigas ha sido bloqueada. Luego le toca a la formación del mensaje MIDI correspondiente y enviarla a un ordenador o conectados para formar un sonido de sintetizador hardware.
Fuente: habrahabr.ru/post/225531/