{"id":895,"date":"2011-11-03T20:32:11","date_gmt":"2011-11-03T18:32:11","guid":{"rendered":"http:\/\/192.168.1.2:8080\/?p=895"},"modified":"2011-11-03T20:32:11","modified_gmt":"2011-11-03T18:32:11","slug":"metawatch-firmware","status":"publish","type":"post","link":"https:\/\/nauj27.com\/blog\/?p=895","title":{"rendered":"MetaWatch Firmware"},"content":{"rendered":"<p>Este verano <a href=\"https:\/\/estore.ti.com\/MSP-WDS430BT2000D-Bluetooth-Wearable-Watch-development-system-with-Digital-display-P2447.aspx\">me compr\u00e9<\/a> un reloj <a href=\"http:\/\/www.metawatch.org\">MetaWatch<\/a>. Este reloj nace seg\u00fan sus creadores como una <a href=\"http:\/\/www.metawatch.org\/developers\/\">plataforma para desarrollo<\/a> de manera que est\u00e1 documentado desde antes de venderse. La documentaci\u00f3n la actualizan, el firmware lo actualizan y la aplicaci\u00f3n para Android la actualizan tambi\u00e9n.<\/p>\n<p>Adem\u00e1s proporcionan el c\u00f3digo fuente tanto de la <a href=\"https:\/\/github.com\/MetaWatchOpenProjects\/MWM-for-Android\">aplicaci\u00f3n para Android<\/a> como del <a href=\"https:\/\/github.com\/MetaWatchOpenProjects\/MetaWatch-WDS11x-IAR\">Firmware<\/a> del mismo. Se me ocurri\u00f3 hacerle una modificaci\u00f3n, y es que cuando se pulsa el primer bot\u00f3n, el de arriba a la derecha, aparece mi tarjeta de visita. En este art\u00edculo explicar\u00e9 de forma resumida el proceso para conseguir mi objetivo.<\/p>\n<p>Lo primero es generar un <a href=\"http:\/\/es.wikipedia.org\/wiki\/C%C3%B3digo_QR\">qrcode<\/a> en la web de <a href=\"http:\/\/zxing.appspot.com\/generator\/\">zxing<\/a>. Se rellena la informaci\u00f3n pertinente y se genera de tama\u00f1o S para que quepa en la pantalla de 96&#215;96 del reloj. Aunque la imagen generada es un poco m\u00e1s grande aprovecharemos el hecho de que tiene un marco blanco alrededor despreciable sin p\u00e9rdida de informaci\u00f3n. Una vez generado se abre con Gimp y se cambia el tama\u00f1o del lienzo a 96&#215;96 recortando la zona blanca del alrededor tanto como sea necesario para que entre, sin redimensionar la imagen. Se guarda como BMP indexado de dos colores sin comprimir y ya tenemos la imagen preparada.<\/p>\n<p>En el c\u00f3digo fuente del firmware del reloj, las im\u00e1genes se encuentran directamente en el formato aceptado por el b\u00fafer de la pantalla, es decir, como array de bytes. Al tener la pantalla 96&#215;96 p\u00edxeles como ya dec\u00edamos antes, se tiene un array de 96 filas con 12 bytes por fila. Doce bytes por ocho bits por byte hacen un total de 96 columnas.<\/p>\n<p>Para convertir cualquier imagen BMP indexada con dos colores a array de bytes he realizado este peque\u00f1o script en python usando parte del c\u00f3digo de <a href=\"https:\/\/github.com\/travisgoodspeed\/PyMetaWatch\">PyMetaWatch<\/a>:<\/p>\n<pre lang=\"python\" line=\"1\">#!\/usr\/bin\/env python\r\nimport sys\r\nimport Image\r\n\r\ndef main():\r\n  image = Image.open(sys.argv[1])\r\n  pix = image.load()\r\n\r\n  for y in range(0, 96):\r\n    rowdat = \"\"\r\n    for x in range(0,96,8):\r\n      byte=0\r\n      for pindex in range(0,8):\r\n        pixel=pix[x+pindex,y]\r\n        if (pixel > 0):\r\n          pixel = 1\r\n\r\n        byte=((byte>>1)|(pixel<<7))\r\n      rowdat=\"%s%s\" % (rowdat,chr(byte))\r\n\r\n    myrow = \"\"\r\n    for dat in rowdat:\r\n      myrow += \"0x%02x,\" % ord(dat)\r\n\r\n    print myrow\r\n\r\nif __name__ == '__main__':\r\n  main()<\/pre>\n<p>Pasando como par\u00e1metro el nombre del archivo BMP devuelve un bloque de caracteres que habr\u00e1 que usar en el c\u00f3digo fuente del firmware. Lo que hice fue volcar la salida a un fichero y despu\u00e9s copiar y pegar el resultado. Con eso es suficiente para nuestro objetivo final, no busc\u00e1bamos hacer un programa de conversi\u00f3n sino que tan solo ha sido una herramienta intermedia.<\/p>\n<p>Finalmente hay que buscar en el fichero <a href=\"https:\/\/github.com\/MetaWatchOpenProjects\/MetaWatch-WDS11x-IAR\/blob\/master\/Watch\/Application\/LcdDisplay.c\">LcdDisplay.c<\/a> la definici\u00f3n de <a href=\"https:\/\/github.com\/MetaWatchOpenProjects\/MetaWatch-WDS11x-IAR\/blob\/master\/Watch\/Application\/LcdDisplay.c#L2019\">pBarCodeImage<\/a> y sustituir su valor por el generado por el script anterior. Se compila el proyecto y se programa el nuevo firmware al reloj siguiendo las mismas instruciones que existen para la <a href=\"http:\/\/www.metawatch.org\/assets\/images\/developers\/MetaWatch_Reflash_your_Watch_Firmware_1.0.pdf\">actualizaci\u00f3n oficial<\/a>. Y <a href=\"https:\/\/twitter.com\/#!\/nauj27\/status\/131725636778725376\">ya est\u00e1<\/a>.<\/p>\n<p>Gracias a <a href=\"http:\/\/draxus.org\/\">draxus<\/a> por encontrar la ubicaci\u00f3n del QRCode original en el c\u00f3digo fuente del firmware.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Este verano me compr\u00e9 un reloj MetaWatch. Este reloj nace seg\u00fan sus creadores como una plataforma para desarrollo de manera que est\u00e1 documentado desde antes de venderse. La documentaci\u00f3n la actualizan, el firmware lo actualizan y la aplicaci\u00f3n para Android la actualizan tambi\u00e9n. Adem\u00e1s proporcionan el c\u00f3digo fuente tanto de la aplicaci\u00f3n para Android como [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[62,5],"tags":[190,204,189,197],"_links":{"self":[{"href":"https:\/\/nauj27.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/895"}],"collection":[{"href":"https:\/\/nauj27.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nauj27.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nauj27.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nauj27.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=895"}],"version-history":[{"count":9,"href":"https:\/\/nauj27.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/895\/revisions"}],"predecessor-version":[{"id":904,"href":"https:\/\/nauj27.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/895\/revisions\/904"}],"wp:attachment":[{"href":"https:\/\/nauj27.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=895"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nauj27.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=895"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nauj27.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=895"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}