{"id":103,"date":"2016-02-26T21:57:43","date_gmt":"2016-02-26T20:57:43","guid":{"rendered":"http:\/\/lab.fawno.com\/?p=103"},"modified":"2022-03-07T01:27:05","modified_gmt":"2022-03-07T00:27:05","slug":"","status":"publish","type":"post","link":"https:\/\/lab.fawno.com\/en\/2016\/02\/26\/aventuras-con-arduino\/","title":{"rendered":"","raw":""},"content":{"rendered":"","protected":false,"raw":""},"excerpt":{"rendered":"","protected":false,"raw":""},"author":1,"featured_media":134,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_coblocks_attr":"","_coblocks_dimensions":"","_coblocks_responsive_height":"","_coblocks_accordion_ie_support":"","_editorskit_title_hidden":false,"_editorskit_reading_time":0,"_editorskit_typography_data":[],"_editorskit_blocks_typography":"","_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}","_es_post_content":"\n

Har\u00e1 como un mes que me lleg\u00f3 mi primer Arduino<\/a>, se trataba de un Arduino Nano<\/a> y estoy encantado con el juguete.<\/p>\n\n\n\n

\"Arduino<\/a>
Arduino Nano (Frontal)<\/figcaption><\/figure><\/div>\n\n\n\n

El caso es que como ten\u00eda por ah\u00ed los t\u00edpicos displays de 7 segmentos<\/a> pues me puse a jugar con un contador de segundos, tremenda tonter\u00eda, lo se.<\/p>\n\n\n\n

La t\u00e9cnica b\u00e1sica para visualizar n\u00fameros en este tipo de displays es unir todos los segmentos e ir visualizando d\u00edgito por d\u00edgito a gran velocidad... de esta forma, igual que en el cine, enga\u00f1amos al ojo y ve todos los d\u00edgitos encendidos cuando en realidad s\u00f3lo hay uno.<\/p>\n\n\n\n

El problema entonces se trata de extraer para cada display el d\u00edgito correspondiente y ah\u00ed es donde me he dado de bruces con algo que ten\u00eda olvidado.<\/p>\n\n\n\n

Veamos, si tenemos el n\u00famero 1234 y queremos visualizar las decenas lo que hacemos es descartar los millares y las centenas y dividir el resto entre 10:<\/p>\n\n\n\n

int Decenas = (Numero % 100) \/ 10;<\/pre>\n\n\n\n

Bueno, pues esto est\u00e1 mal... nos funcionar\u00e1 estupendamente en cualquier ordenador y cualquier programa pero no funcionar\u00e1 bien en Arduino y nos dar\u00e1 errores de redondeo.<\/p>\n\n\n\n

El problema no es la divisi\u00f3n, al ser Decenas<\/em> de tipo entero se truncar\u00e1n los decimales, que es lo que queremos. Arduino no tiene funciones de redondeo, por lo que para evaluar un n\u00famero de coma flotante (float<\/em>) como entero (int<\/em>) lo hace descartando la parte fraccional.<\/p>\n\n\n\n

\u00bfEntonces?, el problema es que antes de la divisi\u00f3n realizamos un m\u00f3dulo de Numero<\/em>. M\u00f3dulo<\/em> <\/a>es la operaci\u00f3n matem\u00e1tica que nos devuelve el resto de una divisi\u00f3n<\/a>. \u00bfArduino calcula mal el m\u00f3dulo?, no. Para calcular el resto de una divisi\u00f3n hay que hacer varias operaciones, todas ellas en coma flotante y Arduino (m\u00e1s concretamente el microcontrolador Atmega328<\/a>) no tiene unidad de coma flotante<\/a> y ah\u00ed radica el problema.<\/p>\n\n\n\n

Al no tener FPU, todos los c\u00e1lculos se hacen en la ALU, que es muy limitada al tratarse de un microcontrolador de 8 bits. As\u00ed que lo que nos encontramos, al realizar el m\u00f3dulo, un c\u00e1lculo redondeado que nos introduce un error en el siguiente c\u00e1lculo...<\/p>\n\n\n\n

La manera correcta de hacer lo que queremos es:<\/p>\n\n\n\n

int Centenas = int(Numero \/ 100) % 10;<\/pre>\n\n\n\n

Ahora extraemos las centenas descartando primero las decenas y unidades (dividiendo entre 100) y luego descartando el resto de d\u00edgitos de la izquierda (m\u00f3dulo 10). Es importante que antes de realizar el m\u00f3dulo le indiquemos al microcontrolador que nos convierta el float<\/em> resultante de la divisi\u00f3n en un int<\/em>. No obstante el IDE de Arduino<\/a> nos devolver\u00e1 un error y no compilar\u00e1 si no lo hacemos.<\/p>\n\n\n\n

Se puede hacer un bucle para ir extrayendo todos los d\u00edgitos:<\/p>\n\n\n\n

for (int d = 0; d &lt; NumeroDeDigitos; d++) {\n  int N = int(Numero \/ pow(10, d)) % 10;\n}<\/pre>\n\n\n\n

Y ya est\u00e1, problema resuelto... pero que me ha tenido loco dos semanas.<\/p>\n\n\n\n

Ahora vendr\u00e1 el listo y me dir\u00e1 que c\u00f3mo no me he dado cuenta antes... pero el listo se olvida que todas las CPU desde el i486<\/a> llevan la FPU incorporada:<\/p>\n\n\n\n

\"https:\/\/commons.wikimedia.org\/wiki\/File%3A80486DX2_arch.svg\"<\/a>
Appaloosa [GFDL (http:\/\/www.gnu.org\/copyleft\/fdl.html) or CC-BY-SA-3.0 (http:\/\/creativecommons.org\/licenses\/by-sa\/3.0\/)], via Wikimedia Commons<\/figcaption><\/figure><\/div>\n\n\n\n

Y claro, eso fue ayer mismo por el 1989, casi nada. Adem\u00e1s el i386<\/a> ya era un procesador de 32 bits (a\u00f1o 1986) y aunque careciera de FPU, su ALU daba mejores resultados que la sencilla l\u00f3gica de 8 bits del Atmega, no obstante estamos hablando de 4 veces m\u00e1s bits para representar los mismos n\u00fameros, por lo que es evidente que la precisi\u00f3n es mucho mayor.<\/p>\n\n\n\n

Otro d\u00eda, ya os contar\u00e9 m\u00e1s cosas de Arduino.<\/p>\n","_es_post_name":"aventuras-con-arduino","_es_post_excerpt":"","_es_post_title":"Aventuras con Arduino","_en_post_content":"","_en_post_name":"","_en_post_excerpt":"","_en_post_title":"","edit_language":"en","footnotes":""},"categories":[19,14,3],"tags":[20],"ninja_gutenberg_blocks_featured_media_urls":{"thumbnail":["https:\/\/lab.fawno.com\/wp-content\/uploads\/2016\/03\/ArduinoNano_Front-150x150.png",150,150,true],"ninja_gutenberg_blocks_landscape_large":["https:\/\/lab.fawno.com\/wp-content\/uploads\/2016\/03\/ArduinoNano_Front.png",1059,413,false],"ninja_gutenberg_blocks_portrait_large":["https:\/\/lab.fawno.com\/wp-content\/uploads\/2016\/03\/ArduinoNano_Front.png",1059,413,false],"ninja_gutenberg_blocks_square_large":["https:\/\/lab.fawno.com\/wp-content\/uploads\/2016\/03\/ArduinoNano_Front.png",1059,413,false],"ninja_gutenberg_blocks_landscape":["https:\/\/lab.fawno.com\/wp-content\/uploads\/2016\/03\/ArduinoNano_Front.png",600,234,false],"ninja_gutenberg_blocks_portrait":["https:\/\/lab.fawno.com\/wp-content\/uploads\/2016\/03\/ArduinoNano_Front.png",600,234,false],"ninja_gutenberg_blocks_square":["https:\/\/lab.fawno.com\/wp-content\/uploads\/2016\/03\/ArduinoNano_Front.png",600,234,false],"full":["https:\/\/lab.fawno.com\/wp-content\/uploads\/2016\/03\/ArduinoNano_Front.png",1059,413,false]},"_links":{"self":[{"href":"https:\/\/lab.fawno.com\/en\/wp-json\/wp\/v2\/posts\/103"}],"collection":[{"href":"https:\/\/lab.fawno.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/lab.fawno.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/lab.fawno.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/lab.fawno.com\/en\/wp-json\/wp\/v2\/comments?post=103"}],"version-history":[{"count":22,"href":"https:\/\/lab.fawno.com\/en\/wp-json\/wp\/v2\/posts\/103\/revisions"}],"predecessor-version":[{"id":1855,"href":"https:\/\/lab.fawno.com\/en\/wp-json\/wp\/v2\/posts\/103\/revisions\/1855"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/lab.fawno.com\/en\/wp-json\/wp\/v2\/media\/134"}],"wp:attachment":[{"href":"https:\/\/lab.fawno.com\/en\/wp-json\/wp\/v2\/media?parent=103"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/lab.fawno.com\/en\/wp-json\/wp\/v2\/categories?post=103"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/lab.fawno.com\/en\/wp-json\/wp\/v2\/tags?post=103"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}