Tag Archives: C

Programador horario con Arduino

¡Hola a tod@s!

Últimamente estoy inmerso en un proyecto con Arduino. El proyecto en cuestión trata el diseño y programación de un controlador para la Pecera del Quinto. Uno de los primeros escollos a resolver es el programador horario y para ello he hecho la siguiente función. La función between(..) permite saber si la hora actual (o cualquier otra) está entre dos horas diferentes, además permite incluir una hora final en el siguiente día (ver ejemplo).

Código de la función:

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
/*
 * Between is a method to check if current time is between two different times (initial time and final time). This method supports a 'final time' in the next day.
 * @param currHour integer (0-23) with the current hour.
 * @param currMinute integer (0-59) with the current minute.
 * @param initHour integer (0-23) with the initial hour.
 * @param initHour integer (0-59) with the initial minute.
 * @param finalHour integer (0-23) with the final hour.
 * @param finalMinute integer (0-59) with the final minute.
 * @return true if the current hour is between the two times (initial and final)
 * @author Oscar Sanchez Montaner (OSanchezMon)
 */
public static boolean between(int currHour, int currMinute, int initHour, int initMinute, int finalHour, int finalMinute) {
    boolean result = false;
 
    // Converting times to minutes.
    int  on = initHour  * 60 +  initMinute;
    int now = currHour  * 60 +  currMinute;
    int off = finalHour * 60 + finalMinute;
 
    // If final time is in the next day...
    if (finalHour < initHour) { // ... must first check if current time is above 12AM (24)...
        if (now > off) {
	    now += 1440; // ... if it is above; increase it 1440 minutes.
	}
	off += 1440; // Final time (for the next day) is always increased 1440 minutes.
    }
    // Development information.
    if (DEBUG_ON) {
        Serial.print("On: "); Serial.print(on); Serial.print(", Now: ");
        Serial.print(now); Serial.print(", Off: "); Serial.println(off);
    }
    // Check if current time is between initial and final time.
    if (now >= on && now < off) {
        result = true;
    }
 
    return result;
}

En el siguiente ejemplo se quiere saber si la hora actual está comprendida entre las 23:10 y las 10:10 (de la mañana siguiente).

Ejemplo de utilización:

1
2
3
4
5
6
7
if (between(hora_actual, minuto_actual, 23, 10, 10, 10)) {
    if (!relay02On) {
      digitalWrite(relay02Pin, HIGH);
      relay02On = true;
      logger("Relay 02 enabled.");
    }
}

Resultados de diferentes casos de prueba:

1
2
3
4
5
6
between(9, 0, 23, 10,  8, 59)); // On: 1390, Now: 1980, Off: 1979 -> false
between(9, 0, 23, 10,  9,  0)); // On: 1390, Now:  540, Off: 1980 -> false
between(9, 0, 23, 10,  9,  1)); // On: 1390, Now:  540, Off: 1981 -> false
between(9, 0, 10, 10,  8, 59)); // On:  610, Now: 1980, Off: 1979 -> false
between(9, 0,  8, 10,  9,  1)); // On:  490, Now:  540, Off:  541 ->  true
between(9, 0,  8, 10,  8, 11)); // On:  490, Now:  540, Off:  491 -> false

Tetris y C ofuscado

Desde Bitelia podemos leer que “detrás” de Micro Tetris podemos encontrar las 19 líneas

long h[4];t(){h[3]-=h[3]/3000;setitimer(0,h,0);}c,d,l,v[]={(int)t,0,2},w,s,I,K
=0,i=276,j,k,q[276],Q[276],*n=q,*m,x=17,f[]={7,-13,-12,1,8,-11,-12,-1,9,-1,1,
12,3,-13,-12,-1,12,-1,11,1,15,-1,13,1,18,-1,1,2,0,-12,-1,11,1,-12,1,13,10,-12,
1,12,11,-12,-1,1,2,-12,-1,12,13,-12,12,13,14,-11,-1,1,4,-13,-12,12,16,-11,-12,
12,17,-13,1,-1,5,-12,12,11,6,-12,12,24};u(){for(i=11;++i&lt;264;)if((k=q[i])-Q[i]
){Q[i]=k;if(i-++I||i%12&lt;1)printf("33[%d;%dH",(I=i)/12,i%12*2+28);printf(
"33[%dm  "+(K-k?0:5),k);K=k;}Q[263]=c=getchar();}G(b){for(i=4;i--;)if(q[i?b+
n[i]:b])return 0;return 1;}g(b){for(i=4;i--;q[i?x+n[i]:x]=b);}main(C,V,a)char*
*V,*a;{h[3]=1000000/(l=C&gt;1?atoi(V[1]):2);for(a=C&gt;2?V[2]:"jkl pq";i;i--)*n++=i&lt;
25||i%12&lt;2?7:0;srand(getpid());system("stty cbreak -echo stop u");sigvec(14,v,
0);t();puts("33[H33[J");for(n=f+rand()%7*4;;g(7),u(),g(0)){if(c&lt;0){if(G(x+
12))x+=12;else{g(7);++w;for(j=0;j&lt;252;j=12*(j/12+1))for(;q[++j];)if(j%12==10){
for(;j%12;q[j--]=0);u();for(;--j;q[j+12]=q[j]);u();}n=f+rand()%7*4;G(x=17)||(c
=a[5]);}}if(c==*a)G(--x)||++x;if(c==a[1])n=f+4**(m=n),G(x)||(n=m);if(c==a[2])G
(++x)||--x;if(c==a[3])for(;G(x+12);++w)x+=12;if(c==a[4]||c==a[5]){s=sigblock(
8192);printf("33[H33[J33[0m%dn",w);if(c==a[5])break;for(j=264;j--;Q[j]=
0);while(getchar()-a[4]);puts("33[H33[J33[7m");sigsetmask(s);}}d=popen(
"stty -cbreak echo stop 23;sort -mnr -o HI - HI;cat HI","w");fprintf(d,
"%4d from level %1d by %sn",w,l,getlogin());pclose(d);}

que en su día valieran para ganar el concurso de código C ofuscado. Según la publicación el código es perfectamente compilable y funciona correctamente.

¡Finalizado el PFC!

El pasado viernes 11 de junio de 2010, a las 24:00, finalizaba el plazo de entrega de la memoria y la presentación del PFC (de 2º ciclo de Ingeniería Informática). El PFC tenía como objectivo diseñar e implementar una herramienta de soporte al diagnóstico de dolencias y enfermedades en el campo de la fisioterapia. Dado que es un campo muy vasto y el tiempo era más bien escaso, a mitad de proyecto se decidió reducir los objetivos a lo que sería la primera fase del proyecto general: utilizar técnicas de visión por computador para analizar y extraer toda la información de la imagen de un paciente, con marcadores ubicados en el cuerpo.

Más adelante añadiré una página sobre el proyecto, al lado de la página del PFC de la Ingeniería Técnica.

¡Ups… se me olvidaba decir la nota! ¡¡¡Un Excelente!!! 🙂

QMetaObject::connectSlotsByName: No matching signal for on_

If you have this warning message during the execution of you Qt application, your solution is: changing the name of the method, because the slots that starts with on_ are reserved for QMetaObject’s auto-connect feature.

For more info, please read: Widgets and dialogs with auto-connect

Visual Studio 2010

El pasado martes 13 asistí a la presentación de Microsoft Visual Studio 2010 en el auditorio Axa de L’Illa Diagonal (Barcelona). La presentación empezó como empiezan todos los eventos de este tipo: con una charla del tipo “somos cojonudos”, “nuestro nuevo producto es la bomba”, etc. La verdad que no me esperaba nada realmente nuevo y tengo que admitir que me dejó gratamente sorprendido todo lo que envuelve a Team Fundation Server. Por lo que entendí del producto, no es únicamente un repositorio de código (como SourceSafe, Svn, etc.) es un repositorio para todo el ciclo de vida del proyecto y para su, posterior, fase de mantenimiento. Además TFS (Team Fundation Server) es conectable desde clientes web, Visual Studio, Office, SharePoint, incluso desde add-ins que puede realizar la conexión  con Eclipse o cualquier otro IDE. También comentaron que TFS cuenta con plantillas CMMI y Scrum para la gestión del proyecto y que se pueden definir nuevas así como su personalización.

Ya dentro del IDE grata sorpresa al descubrir que por fin Microsoft acepta UML como estándar y así lo refleja en VS2010 dando soporte a UML 2.1. Hay que decir que por lo que he visto VS2010 cuenta con muchas herramientas de generación de diagramas de capas, UML vía ingeniería inversa (bottom-up o up-bottom) y la verdad que están muy bien. También se apoya mucho en la generación automática de código mediante acciones sobre los diagramas o con los ya conocidos snippets.

Durante la demo que se realizó en este apartado se comentó que los diagramas de casos de uso se pueden exportar a TFS para generar automáticamente el diseño funcional. También se nombre un nuevo producto: Visual Studio Test Manager 2010 para realizar pruebas de aceptación y testing en general, que cuenta con opciones como:

  • Defecto accionable y definición de los pasos de la prueba para su posterior automatización.
  • Captura de video de cómo se ha producido el bug.
  • Información del sistema del cliente.
  • Intellitrace: nueva tecnología para tracing automático.

Se citó al futuro Lab Management que, entre otras cosas, ofrecerá virtualización de entornos (prepoducción, etc) con la posibilidad de cargar snapshots para reconstruir automáticamente un entorno, compilación de la aplicación y ejecución automática de pruebas funcionales (e.g.: automatizar cada noche, etc.).

Del punto de vista de Management (y vía TFS) se citó la posibilidad de disponer de cuadros de mando con SharePoint y disponer de toda la potencia del análisis de datos de SQL Server 2008 (SharePoint se apoya en SQL Server) para realizar cubos de información. También es posible abrir tareas desde plantillas Excel que automáticamente se publican y el desarrollador las puede ver en su Visual Studio 2010, donde también puede imputar tiempo (en TFS). En el espacio de proyecto del portal se puede habilitar un Wiki. También hablaron de una versión basic de TFS para mini-proyectos que es instalable en un PC normal (todavía no he encontrado cómo descargarme esta versión 🙁 ).

A mitad de la primera parte del evento nos pusieron unos vídeos (puro marketing) y nos facilitaron la siguiente URL: http://www.delinfinitoalmasalla.com

Luego la gente de Danysoft nos ofreció una mini charla (15 minutos) sobre paralelismo y las virtudes del Intel Parallel Studio para C++ y de su integración en Visual Studio 2008 y futura versión para 2010.

Y antes de ir a comer David Salgado y Luis Fraile hicieron una demo muy divertida y didáctica del nuevo IDE de Microsoft. Donde pudimos ver la exportación/importación de breakpoints y tracepoints. También hay que decir que muchas funcionalidad (tanto del IDE con del framework .net) ya se podían disfrutar en Eclipse (highlight automático de palabras y navegación por ellas) o en Java (inclusión en el framework de clases para la gestión de logs al más puro estilo de Log4J; que también está disponible para .net y funciona muy bien) 😛 … aunque ellos lo vendieron como la “Ostia en patinete”.

Por la tarde todo fue un poco más de lo mismo pero centrado en ASP.NET (v 4.0) y SharePoint. Insistieron que desde SharePoint se pueden hacer aplicaciones web muy chulas y dieron datos como que Microsoft ya ha vendido más de 100 millones de licencias para SharePoint; unas muy buenas cifras para un producto bastante nuevo. También comentaron que SharePoint 2010 únicamente está disponible en 64bits.

Y para finalizar se hablo de Silverlight 4.0 (que se hacía oficial el mismo día) y como con este producto, que nació en respuesta a Flash, está destinado (según la gente de Redmond) a convertirse en un único producto para la visualización de aplicaciones, webs, juegos, etc. des de cualquier dispositivo. Según Microsoft, la gente quiere consumir servicios sin preocuparse del soporte (ordenador, teléfono móvil, consola de video juegos, etc.) por ello con Silverlight, en un futuro y con “pocas” modificaciones, se podrán modificar todas las aplicaciones para que utilicen Silverlight.

Y hasta este punto llegó la presentación de Visual Studio 2010. Yo me quedo con el TFS y SharePoint y el resto ya se verá.

Visual Studio 2010

This project is not a CDT project

If you’re using Eclipse and when you want to see/set the C/C++ General or C/C++ Build properties and see this message, your problem is: .cproject file has disappear 🙁 and if you doesn’t have a backup, the fastest way is to create a dummy C/C++ project, copy the .cproject file in you project and modify that changes that you want.

Conocer la IP asociada a un interfaz de red (solo para Linux)

Transcribo una receta, de código Python, publicada en ActiveState Code por Paul Cannon, donde se ve como conocer la dirección IP asociada a un interfaz de red (bajo Linux) mediante la llamada a sistema ioctl SIOCGIFADDR.

1
2
3
4
5
6
7
8
9
10
11
import socket
import fcntl
import struct
 
def get_ip_address(ifname):
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    return socket.inet_ntoa(fcntl.ioctl(
        s.fileno(),
        0x8915, # SIOCGIFADDR
        struct.pack('256s', ifname[:15])
    )[20:24])

Ejemplo de llamada:

get_ip_address('lo')

Con resultado: 127.0.0.1

Otro ejemplo de llamada:

get_ip_address('eth0')

Con resultado: 192.168.50.19

Tal y como comenta el autor, probablemente esta solución únicamente funcione bajo Linux, dada la dependencia de este con ciertas estructuras (tamaño, etc.) en C y donde SIOCGIFADDR es 0x8915. Incluso es probable que únicamente funcione bajo kernels 2.4 y 2.6. Bajo otras distribuciones de Unix puede ser que requiera algún ajuste; que si alguien sabe siempre será bienvenido.