|
|
Línea 33: |
Línea 33: |
| | | |
| == Código fuente == | | == Código fuente == |
− | Mientras creamos un nuevo repositorio para este tipo de proyectos, puedes descargarte el código desde el [https://lists.guifi.net/pipermail/guifi-rdes/2012-January/022659.html mensaje original] en la lista de correo.
| + | El código fuente está disponible en el repositorio de Gitorious guifi-misc: |
− | | + | * https://gitorious.org/guifi-altres/guifi-misc |
− | <syntaxhighlight lang="c">
| + | * https://gitorious.org/guifi-altres/guifi-misc/blobs/master/GuifiReset/guifireset.c |
− | ///////////////////////////////////////////////////////////////////////////////
| + | |
− | //////// CONTROL DE WATCHDOG REMOT PER A REINICIAR NODES GUIFI.NET
| + | |
− | ////////
| + | |
− | //////// Josep Figueras i Franch
| + | |
− | ////////
| + | |
− | //////// Gener - 2011
| + | |
− | ////////
| + | |
− | //////// V1.01 BETA
| + | |
− | ////////
| + | |
− | ////////
| + | |
− | ////////
| + | |
− | //////// * Descripció del Pinout - PIC16F877 *
| + | |
− | ////////
| + | |
− | //////// ---------------------------------
| + | |
− | ////////
| + | |
− | //////// RA0 = Out Relé per atacar al botó de Reset
| + | |
− | ////////
| + | |
− | //////// RA1 =
| + | |
− | ////////
| + | |
− | //////// RA2 =
| + | |
− | ////////
| + | |
− | //////// RA3 =
| + | |
− | ////////
| + | |
− | //////// RA4 =
| + | |
− | ////////
| + | |
− | //////// RA5 =
| + | |
− | ////////
| + | |
− | //////// RB0 =
| + | |
− | ////////
| + | |
− | //////// RB1 =
| + | |
− | ////////
| + | |
− | //////// RB2 =
| + | |
− | ////////
| + | |
− | //////// RB3 =
| + | |
− | ////////
| + | |
− | //////// RB4 =
| + | |
− | ////////
| + | |
− | //////// RB5 =
| + | |
− | ////////
| + | |
− | //////// RB6 =
| + | |
− | ////////
| + | |
− | //////// RB7 =
| + | |
− | ////////
| + | |
− | //////// RC0 =
| + | |
− | ////////
| + | |
− | //////// RC1 =
| + | |
− | ////////
| + | |
− | //////// RC2 =
| + | |
− | ////////
| + | |
− | //////// RC3 =
| + | |
− | ////////
| + | |
− | //////// RC4 =
| + | |
− | ////////
| + | |
− | //////// RC5 =
| + | |
− | ////////
| + | |
− | //////// RC6 = TX RS-232C
| + | |
− | ////////
| + | |
− | //////// RC7 = RX RS-232C
| + | |
− | ////////
| + | |
− | //////// RD0 =
| + | |
− | ////////
| + | |
− | //////// RD1 =
| + | |
− | ////////
| + | |
− | //////// RD2 =
| + | |
− | ////////
| + | |
− | //////// RD3 =
| + | |
− | ////////
| + | |
− | //////// RD4 =
| + | |
− | ////////
| + | |
− | //////// RD5 =
| + | |
− | ////////
| + | |
− | //////// RD6 =
| + | |
− | ////////
| + | |
− | //////// RD7 =
| + | |
− | ////////
| + | |
− | //////// RE0 =
| + | |
− | ////////
| + | |
− | //////// RE1 =
| + | |
− | ////////
| + | |
− | //////// RE2 =
| + | |
− | ////////
| + | |
− | ///////////////////////////////////////////////////////////////////////////////
| + | |
− | // END RESUM PINOUT //
| + | |
− | | + | |
− | #include <16F877A.h>
| + | |
− | //#define use_portb_kbd
| + | |
− | | + | |
− | #define FALS 0
| + | |
− | #define CERT 1
| + | |
− | #define ON 1
| + | |
− | #define OFF 0
| + | |
− | #define DEFECTE 69
| + | |
− | #define START 0xFF
| + | |
− | #define PintaMenu 222
| + | |
− | | + | |
− | //Opcions de la màquina d'estats de la RTCC INT
| + | |
− | #define Dorm 1
| + | |
− | | + | |
− | #use delay(clock = 20000000) //Rellotge
| + | |
− | fixat a 20 MHz
| + | |
− | #use rs232(baud=57600, xmit=PIN_C6, rcv=PIN_C7)
| + | |
− | #fuses HS,NOWDT,PROTECT,NOLVP //Treballem
| + | |
− | amb un cristall d'alta velocitat de 20MHz [HS = High Speed]
| + | |
− | | + | |
− | //desactivem el Watchdog i protegim el codi
| + | |
− | | + | |
− | //Tot seguit donem noms mnemotècnics a les @'s dels ports utilitzats
| + | |
− | //Aquestes direccions les trobem a la pàgina 8 del datasheet (mapa de
| + | |
− | memòria)
| + | |
− | #byte port_a = 05 //Direcció
| + | |
− | del port A
| + | |
− | #byte port_b = 06 //Direcció
| + | |
− | del port B
| + | |
− | #byte port_c = 07 //Direcció
| + | |
− | del port C
| + | |
− | | + | |
− | #include <flex_lcd.h>
| + | |
− | //#include <kbd.c>
| + | |
− | | + | |
− | ////////////////////INICI DE LES VARIABLES GLOBALS////////////////////
| + | |
− | //static BYTE MostraSIO; //Variable
| + | |
− | per enviar les mostres cap al S.O.
| + | |
− | static int OpcioRTCC; //Variable
| + | |
− | per a la màquina d'estats de la RTCC
| + | |
− | static char SerialKey = ' '; //Variable
| + | |
− | on hi guardo el caràcter rebut per la SIO
| + | |
− | static int EstatResetNode; //Flag que
| + | |
− | indica si el relé que activa el reset del servidor/node està connectat o
| + | |
− | desconnectat
| + | |
− | | + | |
− | //Flags de control
| + | |
− | static int ExecutaComanda; //Flag que
| + | |
− | executa l'acció escollida per l'usuari quan apreta la tecla 0 o comfirma
| + | |
− | per RS-232
| + | |
− | ////////////////////FI DE LES VARIABLES GLOBALS////////////////////
| + | |
− | | + | |
− | | + | |
− | ////////////////////INICI DELS PROTOTIPUS////////////////////
| + | |
− | void Init (void);
| + | |
− | void NetejaLCD (void);
| + | |
− | void BucleInfinit (void);
| + | |
− | int ConverteixCaracterAEnter(char * caracter);
| + | |
− | ////////////////////FI DELS PROTOTIPUS////////////////////
| + | |
− | | + | |
− | | + | |
− | ////////////////////INICI DE LES INTERRUPCIONS////////////////////
| + | |
− | #int_rda
| + | |
− | void RDA_isr(){
| + | |
− | SerialKey = 0x00;
| + | |
− | if (kbhit()) {
| + | |
− | SerialKey = getchar();
| + | |
− | if(SerialKey != 0x00){
| + | |
− | switch (SerialKey) {
| + | |
− | case 'a':
| + | |
− | //Activo el reset del Servidor/Node | + | |
− | delay_ms(20);
| + | |
− | output_hight (PIN_A0);
| + | |
− | EstatResetNode = ON;
| + | |
− | ExecutaComanda = CERT;
| + | |
− | break;
| + | |
− | | + | |
− | case 'b':
| + | |
− | //Desactivo el reset del Servidor/Node
| + | |
− | delay_ms(20);
| + | |
− | output_low (PIN_A0);
| + | |
− | EstatResetNode = OFF;
| + | |
− | ExecutaComanda = CERT;
| + | |
− | break;
| + | |
− | | + | |
− | case 'c':
| + | |
− | //Envio pel port sèrie quin és l'estat REAL del relé de Reset del
| + | |
− | Servidor/Node
| + | |
− | delay_ms(20);
| + | |
− | printf("%d",EstatResetNode);
| + | |
− | ExecutaComanda = CERT;
| + | |
− | break;
| + | |
− | | + | |
− | case 'd':
| + | |
− | //Envio la cadena "OK" per dir que el sistema PIC està viu
| + | |
− | delay_ms(20);
| + | |
− | printf("OK");
| + | |
− | break;
| + | |
− | | + | |
− | case 'e':
| + | |
− | //Envio pel port sèrie un missatge de benvinguda per comprovar que tinc
| + | |
− | comunicació amb el PIC
| + | |
− | delay_ms(20);
| + | |
− | printf("\nHola, la comunicacio amb el microcontrol.lador funciona!\n");
| + | |
− | ExecutaComanda = CERT;
| + | |
− | break;
| + | |
− | }
| + | |
− | }
| + | |
− | }
| + | |
− | }
| + | |
− | | + | |
− | | + | |
− | #int_RTCC
| + | |
− | void RTCC_isr(){
| + | |
− | switch (OpcioRTCC) {
| + | |
− | case Dorm:
| + | |
− | //No faig res de res dins de la RTCC-INT | + | |
− | break;
| + | |
− | }
| + | |
− | }
| + | |
− | ////////////////////FI DE LES INTERRUPCIONS//////////////////// | + | |
− | | + | |
− | | + | |
− | ////////////////////INICI DEL CODI DE L'APLICACIÓ////////////////////
| + | |
− | void Init (void) {
| + | |
− | //Inicialització
| + | |
− | //Tot el port A i el port E és de sortida
| + | |
− | set_tris_a(0x00);
| + | |
− | set_tris_e(0x00);
| + | |
− | | + | |
− | //Desactivo tots els relés de sortida (Condicions inicials)
| + | |
− | output_low (PIN_A0);
| + | |
− | output_low (PIN_A1);
| + | |
− | output_low (PIN_A2);
| + | |
− | //Desactivo els conversors interns del PIC
| + | |
− | setup_adc_ports(NO_ANALOGS);
| + | |
− | setup_adc(ADC_OFF);
| + | |
− | | + | |
− | //Desactivo el control I2C
| + | |
− | setup_spi(FALSE);
| + | |
− | | + | |
− | //Configuro els timers
| + | |
− | setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2);
| + | |
− | setup_timer_1(T1_DISABLED);
| + | |
− | setup_timer_2(T2_DISABLED,0,1);
| + | |
− | | + | |
− | //Activo la interrupció del port RS-232
| + | |
− | enable_interrupts(int_rda);
| + | |
− | //Activo la interrupció RTCC
| + | |
− | enable_interrupts(INT_RTCC);
| + | |
− | | + | |
− | //Activo les interrupcions | + | |
− | enable_interrupts(GLOBAL);
| + | |
− | | + | |
− | //Programo la RTCC perque no enviï els senyals de control a la memòria,
| + | |
− | etc...
| + | |
− | OpcioRTCC = Dorm;
| + | |
− | | + | |
− | //Espero 100 mseg. perque s'estabilitzi tot el sistema
| + | |
− | delay_ms(100);
| + | |
− | }
| + | |
− | | + | |
− | | + | |
− | ////////////////////INICI DEL BUCLE INFINIT////////////////////
| + | |
− | void BucleInfinit (void) {
| + | |
− | for ( ; ; ) {
| + | |
− | //Eternament el pic no farà res fins que rebi una interrupció.
| + | |
− | //D'això se'n diu tenir bona vida...
| + | |
− | sleep(1);
| + | |
− | }
| + | |
− | }
| + | |
− | ////////////////////FI DEL BUCLE INFINIT////////////////////
| + | |
− | | + | |
− | | + | |
− | void main(void) {
| + | |
− | Init();
| + | |
− | BucleInfinit();
| + | |
− | }
| + | |
− | | + | |
− | int ConverteixCaracterAEnter(char * caracter) {
| + | |
− | //Funció "tonta" que converteix els caràcters Ascii als seus corresponents
| + | |
− | valors enters
| + | |
− | return (caracter - 48);
| + | |
− | }
| + | |
− | </syntaxhighlight>
| + | |
| | | |
| == Posibles mejoras == | | == Posibles mejoras == |
Las máquinas no son perfectas y muchas veces alcanzan estados que el programador no previno o que por otros motivos no pudo arreglar. En muchos de esos casos, la mejor solución es "apagar y encender".
Aquí se describe una posible solución casera para reiniciar nodos de forma remota y que puede crear cualquiera con ganas y unos conocimientos básicos de electrónica. En este prototipo, el relé en lugar de alimentarse a 12VDc funciona directamente a 5VDc, por tanto, cogiendo únicamente 5V del PC podemos alimentar todo el sistema sin ninguna fuente de alimentación extra.
¡Si haces alguna mejora sobre este prototipo, acuérdate de compartirla también con nosotros!
Haz click en las imágenes para verlas más grandes.