{"id":170,"date":"2016-03-19T23:38:04","date_gmt":"2016-03-19T22:38:04","guid":{"rendered":"http:\/\/lab.fawno.com\/?p=170"},"modified":"2024-09-06T22:30:43","modified_gmt":"2024-09-06T20:30:43","slug":"","status":"publish","type":"post","link":"https:\/\/lab.fawno.org.es\/en\/2016\/03\/19\/frontal-de-descodificador\/","title":{"rendered":"","raw":""},"content":{"rendered":"","protected":false,"raw":""},"excerpt":{"rendered":"","protected":false,"raw":""},"author":1,"featured_media":144,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_coblocks_attr":"","_coblocks_dimensions":"","_coblocks_responsive_height":"","_coblocks_accordion_ie_support":"","_es_post_content":"<!-- wp:paragraph {\"editorskit_typography\":{\"family\":\"\",\"name\":\"\",\"weight\":\"\"}} -->\n<p>Revisando en el trastero todo aquello que me pudiera servir para <a href=\"https:\/\/lab.fawno.org.es\/2016\/03\/18\/mis-arduinos\/\">mis arduinos<\/a>, me encontr\u00e9 alg\u00fan que otro descodificador. De uno de ellos obtuve este panel:<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:image {\"id\":144,\"align\":\"center\",\"editorskit_typography\":{\"family\":\"\",\"name\":\"\",\"weight\":\"\"}} -->\n<figure class=\"wp-block-image aligncenter\"><a href=\"https:\/\/lab.fawno.org.es\/wp-content\/uploads\/2016\/03\/PanelPCB_Front.png\" rel=\"attachment wp-att-144 noopener noreferrer\"><img src=\"https:\/\/lab.fawno.org.es\/wp-content\/uploads\/2016\/03\/PanelPCB_Front-1024x275.png\" alt=\"Panel frontal descodificador (Frontal)\" class=\"wp-image-144\"\/><\/a><figcaption class=\"wp-element-caption\">Panel frontal descodificador (Frontal)<\/figcaption><\/figure>\n<!-- \/wp:image -->\n\n<!-- wp:paragraph -->\n<p>B\u00e1sicamente tenemos ocho botones, un display de 4 d\u00edgitos, dos leds bicolores (rojo-verde) y tres de color (rojo, amarillo, verde) y un receptor IR con su mando a distancia... todo por el m\u00f3dico precio de averiguar c\u00f3mo demonios controlar esto con un Arduino. Ten\u00eda la esperanza de que al tener tantos componentes en la placa y s\u00f3lo un bus de diez l\u00edneas como \u00fanica comunicaci\u00f3n con la placa base ser\u00eda posible controlar el panel de forma sencilla con Arduino.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>As\u00ed que lo primero que hice fue revisar la trasera del frontal para ver qu\u00e9 circuitos integrados (aka garrapatas negras) lleva el trasto:<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:image {\"id\":145,\"align\":\"center\",\"editorskit_typography\":{\"name\":\"\",\"weight\":\"\"}} -->\n<figure class=\"wp-block-image aligncenter\"><a href=\"https:\/\/lab.fawno.org.es\/wp-content\/uploads\/2016\/03\/PanelPCB_Rear.png\" rel=\"attachment wp-att-145 noopener noreferrer\"><img src=\"https:\/\/lab.fawno.org.es\/wp-content\/uploads\/2016\/03\/PanelPCB_Rear-1024x271.png\" alt=\"Panel frontal descodificador (Trasera)\" class=\"wp-image-145\"\/><\/a><figcaption class=\"wp-element-caption\">Panel frontal descodificador (Trasera)<\/figcaption><\/figure>\n<!-- \/wp:image -->\n\n<!-- wp:paragraph -->\n<p>En la foto no se observa, pero con una lupa y la iluminaci\u00f3n adecuada pude comprobar que los dos \u00fanicos circuitos integrados son el MM74HC595M:<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:image {\"id\":171,\"align\":\"center\",\"editorskit_typography\":{\"name\":\"\",\"weight\":\"\"}} -->\n<figure class=\"wp-block-image aligncenter\"><a href=\"https:\/\/lab.fawno.org.es\/wp-content\/uploads\/2016\/03\/MM74HC959M.png\" rel=\"attachment wp-att-171 noopener noreferrer\"><img src=\"https:\/\/lab.fawno.org.es\/wp-content\/uploads\/2016\/03\/MM74HC959M-300x234.png\" alt=\"MM74HC959M\" class=\"wp-image-171\"\/><\/a><figcaption class=\"wp-element-caption\">MM74HC959M<\/figcaption><\/figure>\n<!-- \/wp:image -->\n\n<!-- wp:paragraph -->\n<p>Una r\u00e1pida b\u00fasqueda nos da como resultado que el <a href=\"https:\/\/www.fairchildsemi.com\/products\/logic\/flip-flops-latches-registers\/registers\/MM74HC595.html\" target=\"_blank\" rel=\"noopener noreferrer\">MM74HC595M<\/a> es un registro de desplazamiento de 8 bits (8bits Shift Register) del que hay sobrada <a href=\"https:\/\/www.arduino.cc\/en\/Tutorial\/ShiftOut\" target=\"_blank\" rel=\"noopener noreferrer\">documentaci\u00f3n<\/a> con respecto a <a href=\"https:\/\/www.prometec.net\/shift-registers\/\" target=\"_blank\" rel=\"noopener noreferrer\">c\u00f3mo controlarlo con Arduino<\/a>. As\u00ed que mi primera intuici\u00f3n empezaba a cobrar fuerza.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>Sin embargo necesitaba saber el esquema para poder averiguar c\u00f3mo controlar el panel. As\u00ed que en dos o tres d\u00edas ya ten\u00eda los primeros esquemas a mano de la parte de los cuatro d\u00edgitos de siete segmentos y en dos o tres d\u00edas m\u00e1s el <a href=\"https:\/\/lab.fawno.org.es\/wp-content\/uploads\/2016\/03\/Panel.pdf\">esquema definitivo<\/a>:<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:image {\"id\":173,\"align\":\"center\",\"editorskit_typography\":{\"name\":\"\",\"weight\":\"\"}} -->\n<figure class=\"wp-block-image aligncenter\"><a href=\"https:\/\/lab.fawno.org.es\/wp-content\/uploads\/2016\/03\/Panel.png\" rel=\"attachment wp-att-173 noopener noreferrer\"><img src=\"https:\/\/lab.fawno.org.es\/wp-content\/uploads\/2016\/03\/Panel-230x300.png\" alt=\"Panel frontal descodificador (esquema)\" class=\"wp-image-173\"\/><\/a><figcaption class=\"wp-element-caption\">Panel frontal descodificador (esquema)<\/figcaption><\/figure>\n<!-- \/wp:image -->\n\n<!-- wp:paragraph -->\n<p>Del esquema se puede ver que con s\u00f3lo 8 cables (6 si descontamos Vcc y GND) podemos controlar los 4 d\u00edgitos de siete segmenos, los 5 leds (dos de ellos bicolor), recibir las se\u00f1ales del mando a distancia y saber qu\u00e9 pulsador es el que se ha accionado.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>Lo m\u00e1s f\u00e1cil es utilizar el receptor de infrarrojos, ya que con conectar la alimentaci\u00f3n (pin 1 del panel a GND y pin 9 a +5V) y conectar el pin 2 del panel a una entrada digital del Arduino ya podemos <a href=\"https:\/\/playground.arduino.cc\/Code\/InfraredReceivers\" target=\"_blank\" rel=\"noopener noreferrer\">jugar<\/a> con un <a href=\"https:\/\/geekayuda.blogspot.com.es\/2013\/12\/arduino-sensor-ir-infrarrojo.html\" target=\"_blank\" rel=\"noopener noreferrer\">mando a distancia<\/a>.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>Evidentemente para jugar con el resto de elementos hay que pensar un poco m\u00e1s. Por ejemplo, algo que en los ejemplos y circuitos que he visto con Arduino y el 74595&nbsp;suelen obviar el pin <em>Enable<\/em> de estos chips. El panel lo utiliza y le da salida, siendo muy \u00fatil pues si en setup lo ponemos en <em>HIGH<\/em> antes de poner el panel en su configuraci\u00f3n inicial (la que decidamos que deba ser) y una vez establecida dicha configuraci\u00f3n ponemos el <em>Enable<\/em> a <em>LOW<\/em> habremos tenido el panel completamente apagado (los leds y los segmentos de los d\u00edgitos) hasta obtener una situaci\u00f3n estable y conocida:<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:enlighter\/codeblock {\"language\":\"cpp\",\"theme\":\"dracula\",\"editorskit_typography\":{\"family\":\"\",\"name\":\"\",\"weight\":\"\"}} -->\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"dracula\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">void setup() {\n  pinMode(latchPin, OUTPUT);\n  pinMode(clockPin, OUTPUT);\n  pinMode(enablePin, OUTPUT);\n  pinMode(dataPin, OUTPUT);\n  pinMode(swPin, INPUT);\n\n  \/\/ Desactivamos las salidas de los 74595\n  digitalWrite(enablePin, HIGH);\n\n  \/\/ Establecemos la condici\u00f3n inicial del Panel\n  digitalWrite(latchPin, LOW);\n  shiftOut(dataPin, clockPin, LSBFIRST, 0b00001111);\n  shiftOut(dataPin, clockPin, LSBFIRST, 0b00110000);\n  digitalWrite(latchPin, HIGH);\n\n  \/\/ Activamos las salidas de los 74595\n  digitalWrite(enablePin, LOW);\n}<\/pre>\n<!-- \/wp:enlighter\/codeblock -->\n\n<!-- wp:paragraph -->\n<p>La verdad, el resultado es muy chulo, sobre todo por las opciones que me da sin tener que cablear o soldar nada:<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:embed {\"url\":\"https:\/\/www.youtube.com\/watch?v=GygqIUF_WFI\",\"type\":\"video\",\"providerNameSlug\":\"youtube\",\"responsive\":true,\"className\":\"wp-embed-aspect-16-9 wp-has-aspect-ratio\",\"editorskit_typography\":{\"family\":\"\",\"name\":\"\",\"weight\":\"\"}} -->\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\nhttps:\/\/www.youtube.com\/watch?v=GygqIUF_WFI\n<\/div><\/figure>\n<!-- \/wp:embed -->\n\n<!-- wp:paragraph -->\n<p>Y el c\u00f3digo completo:<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:enlighter\/codeblock {\"language\":\"cpp\",\"theme\":\"dracula\"} -->\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"dracula\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">const byte Digits[] = {\n  0b00001110, \/\/ Digit 0\n  0b00001101, \/\/ Digit 1\n  0b00001011, \/\/ Digit 2\n  0b00000111, \/\/ Digit 3\n};\n\nconst byte swMask = 0b00001111;\n\nconst byte buttons[] = {\n  0b10001110, \/\/ 0 SW1 POWER\n  0b10001101, \/\/ 1 SW2 UP\n  0b10001011, \/\/ 2 SW3 DOWN\n  0b10000111, \/\/ 3 SW4 RADIO\n  0b01001110, \/\/ 4 SW5 MENU\n  0b01001101, \/\/ 5 SW6 LEFT\n  0b01001011, \/\/ 6 SW7 YES\n  0b01000111, \/\/ 7 SW8 RIGHT\n};\n\nconst byte dec7seg[] = {\n  0b00111111, \/\/ 0\n  0b00000110, \/\/ 1\n  0b01011011, \/\/ 2\n  0b01001111, \/\/ 3\n  0b01100110, \/\/ 4\n  0b01101101, \/\/ 5\n  0b01111101, \/\/ 6\n  0b00000111, \/\/ 7\n  0b01111111, \/\/ 8\n  0b01101111, \/\/ 9\n};\n\nconst byte LedsRight = 0b00001111;\nconst byte LedsRYG_G = 0b00100001;\nconst byte LedsRYG_Y = 0b00100010;\nconst byte LedsRYG_R = 0b00101000;\nconst byte LedsRG_G1 = 0b00010001;\nconst byte LedsRG_R1 = 0b00010010;\nconst byte LedsRG_G4 = 0b00010100;\nconst byte LedsRG_R4 = 0b00011000;\n\n\nconst int dataPin = 11;  \/\/ 74HC595 Pin 14 (GRIS)\nconst int latchPin = 10; \/\/ 74HC595 Pin 12 (VERDE)\nconst int clockPin = 9;  \/\/ 74HC595 Pin 11 (MORADO)\nconst int enablePin = 8; \/\/ 74HC595 Pin 13 (MARRON)\nconst int swPin = 7;     \/\/ AZUL\n\nbyte LedsRG = 0b00000000;\nbyte LedsRYG = 0b00000000;\n\nint wait = 0;\n\nvoid setup() {\n  pinMode(latchPin, OUTPUT);\n  pinMode(clockPin, OUTPUT);\n  pinMode(enablePin, OUTPUT);\n  pinMode(dataPin, OUTPUT);\n  pinMode(swPin, INPUT);\n  digitalWrite(enablePin, HIGH);\n  digitalWrite(latchPin, LOW);\n  shiftOut(dataPin, clockPin, LSBFIRST, 0b00001111);\n  shiftOut(dataPin, clockPin, LSBFIRST, 0b00110000);\n  digitalWrite(latchPin, HIGH);\n  digitalWrite(enablePin, LOW);\n}\n\nvoid Display (int Num, int wait) {\n  for (int d = 0; d &lt; sizeof(Digits); d++) {\n    int N = int(Num \/ pow(10, d)) % 10;\n    digitalWrite(latchPin, LOW);\n    byte dataR = (dec7seg[N] &lt;&lt; 4) | Digits[d];\n    byte dataL = (dec7seg[N] >> 4) | 0b00110000;\n    shiftOut(dataPin, clockPin, LSBFIRST, dataR);\n    shiftOut(dataPin, clockPin, LSBFIRST, dataL);\n    digitalWrite(latchPin, HIGH);\n    delay(wait);\n  }\n}\n\nint readsw () {\n  for (int sw = 0; sw &lt; sizeof(buttons); sw++) {\n    digitalWrite(latchPin, LOW);\n    byte dataR = swMask &amp; buttons[sw];\n    byte dataL = (~swMask) &amp; buttons[sw];\n    shiftOut(dataPin, clockPin, LSBFIRST, dataR);\n    shiftOut(dataPin, clockPin, LSBFIRST, dataL);\n    digitalWrite(latchPin, HIGH);\n    if (digitalRead(swPin) == LOW) return sw;\n  }\n  return -1;\n}\n\nconst byte swLeds[] {\n  0b00000000,\n  LedsRYG_G,\n  LedsRYG_R,\n  LedsRYG_R | LedsRYG_G,\n  LedsRYG_Y,\n  LedsRYG_Y | LedsRYG_G,\n  LedsRYG_Y | LedsRYG_R,\n  LedsRYG_Y | LedsRYG_R | LedsRYG_G,\n};\n\nvoid loop() {\n  int Num = millis() \/ 1000;\n\n\n  LedsRG = 0b00000000;\n  LedsRYG = 0b00000000;\n  int sw = readsw();\n  if (sw >= 0) {\n    LedsRG = LedsRG_G4;\n    LedsRYG = swLeds[sw];\n  }\n  if (Num % 2) LedsRG = LedsRG | LedsRG_R1;\n  switch (sw) {\n    case 1:\n  if (sw == 1) wait += 10;\n      for (int i = 0; i &lt; 10; i++) {\n        Display(wait, 0);        \n        delay(20);\n      }\n      break;\n    case 2:\n  if (sw == 2 &amp;&amp; wait > 0) wait -= 10;\n      for (int i = 0; i &lt; 10; i++) {\n        Display(wait, 0);        \n        delay(20);\n      }\n      break;\n    case 4:\n      Display(wait, 0);\n      break;\n    default:\n      Display(Num, wait);\n  }\n\n  digitalWrite(latchPin, LOW);\n  shiftOut(dataPin, clockPin, LSBFIRST, LedsRight);\n  shiftOut(dataPin, clockPin, LSBFIRST, LedsRYG);\n  digitalWrite(latchPin, HIGH);\n\n  digitalWrite(latchPin, LOW);\n  shiftOut(dataPin, clockPin, LSBFIRST, LedsRight);\n  shiftOut(dataPin, clockPin, LSBFIRST, LedsRG);\n  digitalWrite(latchPin, HIGH);\n}<\/pre>\n<!-- \/wp:enlighter\/codeblock -->\n\n<!-- wp:paragraph -->\n<p>Lo \u00fanico que no estar\u00eda en un c\u00f3digo de producci\u00f3n ser\u00eda la variable <em>wait<\/em> de la funci\u00f3n <em>Display<\/em>, que quedar\u00eda as\u00ed:<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:enlighter\/codeblock {\"language\":\"cpp\",\"theme\":\"dracula\"} -->\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"dracula\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">void Display (int Num) {\n  for (int d = 0; d &lt; sizeof(Digits); d++) {\n    int N = int(Num \/ pow(10, d)) % 10;\n    digitalWrite(latchPin, LOW);\n    byte dataR = (dec7seg[N] &lt;&lt; 4) | Digits[d];\n    byte dataL = (dec7seg[N] >> 4) | 0b00110000;\n    shiftOut(dataPin, clockPin, LSBFIRST, dataR);\n    shiftOut(dataPin, clockPin, LSBFIRST, dataL);\n    digitalWrite(latchPin, HIGH);\n  }\n}<\/pre>\n<!-- \/wp:enlighter\/codeblock -->\n\n<!-- wp:paragraph -->\n<p>\u00bfPor qu\u00e9 introducir una pausa variable entre el refresco de cada d\u00eddito?, pues simplemente como demostraci\u00f3n de que s\u00f3lo uno de los cuatro d\u00edgitos est\u00e1 encendido al mismo tiempo. Vamos, por aumentar el elemento did\u00e1ctico, que a fin de cuentas esa es la excusa con la que me he comprado los juguetes...<\/p>\n<!-- \/wp:paragraph -->","_es_post_name":"frontal-de-descodificador","_es_post_excerpt":"","_es_post_title":"Frontal de descodificador","_en_post_content":"","_en_post_name":"","_en_post_excerpt":"","_en_post_title":"","edit_language":"en","footnotes":""},"categories":[19,30],"tags":[20,31],"class_list":["post-170","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-arduino","category-hardware","tag-arduino","tag-hardware"],"ninja_gutenberg_blocks_featured_media_urls":{"thumbnail":["https:\/\/lab.fawno.org.es\/wp-content\/uploads\/2016\/03\/PanelPCB_Front-150x150.png",150,150,true],"ninja_gutenberg_blocks_landscape_large":["https:\/\/lab.fawno.org.es\/wp-content\/uploads\/2016\/03\/PanelPCB_Front.png",1200,322,false],"ninja_gutenberg_blocks_portrait_large":["https:\/\/lab.fawno.org.es\/wp-content\/uploads\/2016\/03\/PanelPCB_Front.png",1200,322,false],"ninja_gutenberg_blocks_square_large":["https:\/\/lab.fawno.org.es\/wp-content\/uploads\/2016\/03\/PanelPCB_Front.png",1200,322,false],"ninja_gutenberg_blocks_landscape":["https:\/\/lab.fawno.org.es\/wp-content\/uploads\/2016\/03\/PanelPCB_Front.png",600,161,false],"ninja_gutenberg_blocks_portrait":["https:\/\/lab.fawno.org.es\/wp-content\/uploads\/2016\/03\/PanelPCB_Front.png",600,161,false],"ninja_gutenberg_blocks_square":["https:\/\/lab.fawno.org.es\/wp-content\/uploads\/2016\/03\/PanelPCB_Front.png",600,161,false],"full":["https:\/\/lab.fawno.org.es\/wp-content\/uploads\/2016\/03\/PanelPCB_Front.png",1642,441,false]},"_links":{"self":[{"href":"https:\/\/lab.fawno.org.es\/en\/wp-json\/wp\/v2\/posts\/170","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/lab.fawno.org.es\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/lab.fawno.org.es\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/lab.fawno.org.es\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/lab.fawno.org.es\/en\/wp-json\/wp\/v2\/comments?post=170"}],"version-history":[{"count":0,"href":"https:\/\/lab.fawno.org.es\/en\/wp-json\/wp\/v2\/posts\/170\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/lab.fawno.org.es\/en\/wp-json\/wp\/v2\/media\/144"}],"wp:attachment":[{"href":"https:\/\/lab.fawno.org.es\/en\/wp-json\/wp\/v2\/media?parent=170"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/lab.fawno.org.es\/en\/wp-json\/wp\/v2\/categories?post=170"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/lab.fawno.org.es\/en\/wp-json\/wp\/v2\/tags?post=170"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}