Estoy usando un Arduino Mega para ejecutar tres cámaras de escaneo lineal TSL1401R-LF en paralelo. Hice que todo funcionara y la cámara me daba diferentes resultados según la cantidad de luz que les llegaba (es decir, mucha luz me dio un número alto y poca luz me dio un número más pequeño).
Sin embargo, cuando intenté aumentar el FPS de las cámaras al reducir los retrasos sin operaciones, la precisión disminuyó drásticamente y no tengo idea de por qué. De acuerdo con la hoja de datos, los retrasos mínimos para el impulso CLK son 50 ns y un no funcionamiento provoca un retraso de 62,5 ns, por lo que no debería haber ningún problema. ¿Alguien aquí tiene una idea de por qué podría estar sucediendo esto?
Aquí está mi código antes de las no operaciones:
void readPixels()
{
digitalWrite(SI, HIGH);
delayMicroseconds(delayTime/2);
digitalWrite(CLK, HIGH);
delayMicroseconds(delayTime/2);
digitalWrite(SI, LOW);
delayMicroseconds(delayTime/2);
digitalWrite(CLK, LOW);
delayMicroseconds(delayTime);
for(int i = 0; i < 128; i++)
{
digitalWrite(CLK, HIGH);
pixelsArray1[i]=analogRead(Cam1Aout);
pixelsArray2[i]=analogRead(Cam2Aout);
pixelsArray3[i]=analogRead(Cam3Aout);
delayMicroseconds(delayTime);
digitalWrite(CLK, LOW);
delayMicroseconds(delayTime);
}
delayMicroseconds(20);
}
OUTPUT:
Camera 1: 295, 319, 353, 387, 422, 458, 483, 499, 515, 527, 540, 545, 556, 562, 572, 575, 585, 590, 596, 598, 606, 603, 591, 589, 608, 621, 635, 636, 646, 652, 664, 670, 681, 689, 699, 705, 715, 726, 730, 734, 742, 745, 750, 752, 760, 764, 769, 766, 768, 770, 775, 777, 792, 806, 828, 852, 880, 907, 931, 956, 989, 1016, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 980, 986, 935, 935, 893, 892, 856, 847, 812, 801, 774, 760, 731, 713, 683, 647, 605, 564, 513, 470, 410, 369, 323, 289, 347, 376,
Camera 2: 346, 368, 396, 419, 446, 462, 480, 496, 516, 531, 549, 559, 571, 579, 593, 600, 611, 619, 628, 636, 647, 651, 660, 667, 676, 679, 687, 696, 704, 710, 719, 725, 732, 735, 743, 743, 752, 758, 764, 768, 775, 777, 783, 788, 793, 798, 803, 806, 809, 814, 818, 822, 827, 831, 831, 833, 836, 839, 841, 839, 843, 843, 844, 839, 841, 836, 831, 830, 831, 830, 831, 834, 841, 847, 861, 867, 880, 894, 902, 911, 918, 935, 940, 956, 960, 976, 973, 991, 984, 1007, 998, 1020, 998, 1019, 992, 1014, 986, 997, 964, 969, 937, 937, 908, 910, 878, 875, 843, 838, 808, 797, 768, 750, 720, 696, 667, 639, 611, 582, 556, 524, 499, 471, 449, 423, 399, 371, 396, 399,
Camera 3: 472, 491, 507, 512, 526, 551, 564, 572, 583, 588, 583, 586, 587, 593, 603, 604, 604, 608, 611, 617, 617, 621, 625, 629, 635, 641, 635, 645, 661, 668, 671, 675, 678, 680, 685, 688, 688, 690, 691, 694, 696, 701, 701, 704, 699, 706, 705, 706, 713, 715, 718, 719, 719, 719, 720, 721, 723, 731, 737, 736, 739, 743, 748, 751, 755, 758, 760, 763, 766, 768, 769, 773, 775, 777, 777, 780, 787, 791, 790, 787, 781, 779, 769, 763, 760, 758, 755, 750, 743, 741, 744, 748, 743, 740, 750, 755, 774, 783, 790, 797, 802, 810, 807, 818, 806, 807, 796, 796, 785, 777, 759, 748, 728, 715, 696, 681, 664, 647, 625, 606, 579, 558, 536, 508, 484, 467, 432, 427,
Runetime: 2121
Aquí está después de agregar los no-ops:
void readPixels()
{
digitalWrite(SI, HIGH);
delayMicroseconds(delayTime/2);
digitalWrite(CLK, HIGH);
delayMicroseconds(delayTime/2);
digitalWrite(SI, LOW);
delayMicroseconds(delayTime/2);
digitalWrite(CLK, LOW);
delayMicroseconds(delayTime);
for(int i = 0; i < 128; i++)
{
digitalWrite(CLK, HIGH);
pixelsArray1[i]=analogRead(Cam1Aout);
pixelsArray2[i]=analogRead(Cam2Aout);
pixelsArray3[i]=analogRead(Cam3Aout);
__asm__("nop\n\t");
digitalWrite(CLK, LOW);
__asm__("nop\n\t");
}
delayMicroseconds(20);
}
OUTPUT:
Camera 1: 147, 141, 142, 143, 145, 145, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 146, 145, 145, 143, 145, 143, 146, 146, 145, 145, 144, 147, 147, 147, 147, 148, 147, 147, 147, 147, 147, 147, 147, 147, 147, 148, 147, 147, 147, 148, 147, 147, 148, 147, 151, 152, 153, 154, 156, 156, 158, 158, 159, 161, 162, 163, 165, 166, 167, 167, 168, 169, 167, 172, 174, 174, 174, 174, 175, 176, 176, 177, 177, 179, 179, 179, 179, 179, 178, 178, 176, 175, 174, 172, 172, 170, 168, 167, 165, 163, 162, 161, 159, 158, 156, 154, 155, 152, 151, 150, 148, 146, 146, 143, 143, 141, 139, 137, 135, 131, 129, 127, 125, 122, 120, 140, 172,
Camera 2: 162, 161, 164, 164, 167, 166, 165, 167, 169, 167, 170, 171, 171, 169, 172, 171, 172, 171, 172, 172, 172, 172, 173, 172, 173, 172, 174, 173, 174, 173, 174, 174, 176, 174, 175, 170, 175, 174, 176, 175, 185, 175, 176, 175, 176, 175, 176, 176, 176, 176, 176, 176, 177, 176, 177, 176, 176, 176, 177, 176, 177, 176, 177, 176, 176, 176, 176, 176, 176, 175, 176, 175, 176, 176, 177, 177, 179, 177, 179, 179, 179, 179, 181, 181, 183, 183, 184, 184, 185, 185, 186, 185, 187, 186, 187, 187, 188, 185, 186, 184, 185, 183, 183, 181, 181, 179, 179, 176, 176, 174, 174, 172, 171, 170, 167, 164, 164, 162, 161, 159, 159, 156, 157, 154, 153, 152, 169, 198,
Camera 3: 185, 187, 188, 191, 189, 190, 192, 192, 193, 193, 192, 194, 194, 194, 195, 199, 196, 196, 196, 197, 199, 198, 198, 198, 199, 199, 199, 199, 196, 201, 201, 201, 201, 201, 202, 203, 202, 202, 203, 203, 204, 204, 204, 203, 204, 204, 204, 204, 204, 204, 205, 205, 205, 206, 206, 206, 205, 206, 206, 206, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 208, 207, 209, 209, 208, 208, 209, 209, 207, 208, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 208, 209, 209, 209, 211, 211, 211, 211, 211, 211, 211, 210, 210, 209, 209, 207, 207, 206, 206, 204, 203, 203, 201, 199, 200, 198, 195, 195, 195, 193, 167, 179,
Runetime: 1987
Aquí está conmigo usando While Loops:
void readPixels()
{
digitalWrite(SI, HIGH);
delayMicroseconds(delayTime/2);
digitalWrite(CLK, HIGH);
delayMicroseconds(delayTime/2);
digitalWrite(SI, LOW);
delayMicroseconds(delayTime/2);
digitalWrite(CLK, LOW);
delayMicroseconds(delayTime);
int i = 0;
while(i < 128)
{
i++;
digitalWrite(CLK, HIGH);
pixelsArray1[i]=analogRead(Cam1Aout);
pixelsArray2[i]=analogRead(Cam2Aout);
pixelsArray3[i]=analogRead(Cam3Aout);
digitalWrite(CLK, LOW);
}
delayMicroseconds(20);
}
OUTPUT:
Camera 1: 224, 161, 172, 179, 185, 198, 199, 203, 206, 208, 208, 211, 212, 213, 214, 216, 216, 217, 217, 218, 217, 219, 219, 216, 215, 217, 220, 222, 223, 223, 224, 226, 225, 229, 231, 231, 232, 235, 235, 236, 237, 238, 240, 240, 240, 240, 241, 242, 242, 242, 242, 243, 243, 246, 248, 252, 255, 262, 266, 271, 276, 281, 287, 291, 296, 304, 307, 314, 319, 326, 332, 331, 337, 337, 335, 352, 359, 359, 359, 361, 366, 371, 371, 372, 376, 382, 384, 384, 382, 380, 380, 377, 372, 366, 361, 355, 351, 344, 339, 331, 323, 318, 312, 307, 301, 294, 290, 284, 280, 273, 268, 263, 257, 252, 248, 241, 231, 227, 219, 209, 199, 191, 182, 172, 163, 155, 147, 176,
Camera 2: 216, 193, 196, 203, 207, 212, 216, 219, 222, 223, 227, 231, 231, 234, 236, 238, 239, 241, 242, 242, 244, 247, 247, 248, 249, 252, 252, 252, 254, 255, 258, 259, 259, 259, 260, 262, 262, 263, 263, 265, 272, 268, 267, 268, 268, 270, 270, 271, 271, 272, 273, 274, 275, 275, 275, 276, 276, 277, 277, 278, 277, 280, 278, 278, 277, 278, 276, 276, 275, 275, 275, 275, 276, 277, 278, 280, 282, 285, 287, 289, 291, 294, 295, 299, 301, 304, 306, 310, 312, 313, 316, 319, 319, 321, 322, 323, 323, 322, 319, 318, 315, 312, 308, 305, 302, 298, 294, 289, 284, 280, 275, 270, 263, 257, 251, 244, 238, 232, 227, 223, 216, 211, 206, 202, 197, 193, 188, 207,
Camera 3: 0, 231, 235, 238, 240, 243, 247, 250, 252, 254, 255, 255, 255, 255, 257, 259, 260, 260, 260, 262, 260, 263, 264, 265, 266, 267, 268, 268, 269, 273, 274, 276, 275, 276, 277, 278, 278, 279, 279, 280, 280, 280, 281, 281, 281, 281, 283, 283, 283, 284, 284, 285, 285, 285, 286, 286, 286, 286, 287, 289, 289, 289, 290, 291, 291, 292, 293, 293, 294, 294, 295, 295, 295, 295, 295, 296, 297, 298, 299, 299, 298, 297, 296, 295, 294, 294, 292, 292, 291, 290, 289, 291, 291, 290, 289, 291, 292, 295, 298, 300, 302, 304, 304, 307, 307, 307, 305, 304, 304, 303, 300, 297, 294, 289, 287, 283, 280, 275, 272, 269, 263, 259, 255, 252, 246, 241, 237, 212,
Runetime: 1991
Algunas notas:
He optimizado el analogRead();
método con prescalers para que sean más rápidos de lo habitual.
Si bien la salida del segundo código muestra alguna diferencia cuando sostengo un objeto en la línea de visión de las cámaras, es una diferencia mucho menor y solo funciona cuando lo sostengo directamente frente a las cámaras.
Lo que probablemente sucedió es que el compilador decidió optimizar su código y los tiró nop
a la basura. Debe obligar al compilador a mantener intacto su ensamblaje definiéndolo volatile
:
__asm__ __volatile__ ("nop\n\t");
Alternativamente, podría retrasar haciendo algo útil, por ejemplo:
int i = 0;
while(i < 128)
{
i++;
digitalWrite(CLK, HIGH);
pixelsArray1[i]=analogRead(Cam1Aout);
pixelsArray2[i]=analogRead(Cam2Aout);
pixelsArray3[i]=analogRead(Cam3Aout);
digitalWrite(CLK, LOW);
}
PD. La caída en la sensibilidad que está viendo bien puede ser normal. Su hoja de datos dice:
El tiempo de integración mínimo para cualquier conjunto dado está determinado por el tiempo requerido para registrar todos los píxeles en el conjunto y el tiempo para descargar los píxeles. El tiempo requerido para descargar los píxeles es una constante. Por lo tanto, el período de integración mínimo es simplemente una función de la frecuencia del reloj y la cantidad de píxeles en la matriz. Una velocidad de reloj más lenta aumenta el tiempo de integración mínimo y reduce el nivel máximo de luz para la saturación en la salida. El tiempo de integración mínimo que se muestra en esta hoja de datos se basa en la frecuencia de reloj máxima de 8 MHz.
Dado que su código optimizado se ejecuta más rápido, queda menos tiempo para la integración, lo que reduce el valor de salida.
Además, intente agregar un retraso después digitalWrite(CLK, HIGH);
para respetar el ts
tiempo mencionado en la forma de onda en la página 5.
delay(1000);
comando tardaría 2 segundos en lugar de uno). Sin embargo, está bien, gracias por sus sugerencias.Cuando usa digitalWrite
, está haciendo un montón de cosas detrás de escena además de establecer el pin. Esto es necesario porque Arduino combina PWM y la conmutación regular, por lo que hay una arquitectura de fondo impulsada por interrupciones que necesita administración . Al final, un simple interruptor de pin digitalWrite
requiere 100 ciclos de reloj, según este compañero . Por lo tanto, su NOP
es una gota en el cubo de tiempo.
Si desea un mejor control sobre el tiempo, lo que desea usar son los controles AVR de nivel inferior o las bibliotecas que los implementan. Un osciloscopio sería realmente útil para la depuración, pero de lo contrario, se verá obligado a confiar en modelos mentales.
NOP
si digitalWrite
se NOP
ejecuta después de digitalWrite
? ¿El comando no se ejecuta de arriba a abajo o simplemente no entiendo la programación? Para su información, este es mi primer proyecto Arduino.
ammar.cma
sgmm