miércoles, 14 de septiembre de 2011

etapa Regional de Innovación Tecnológica Tehuacan Puebla

Pues hace un buen rato que no escribo nada, y creo que tenia suficiente tiempo para hacerlo antes.

Ahora ya hay mas trabajo que antes, aunque esto, por el momento, no veo remuneración alguna, mas que la entera satisfacción, de hacer bien mi chamba.

Pues como uno de los resultados, el proyecto Gramatical, sigue adelante y ahora con un nuevo integrante, gramabot (aun está en condiciones de prototipo, pero ya está funcional)

el codigo fuente de control, está en lenguaje C, con el compiladr SDCC, programdo usando IDE beta MPLABX y libero el codigo con licencia GPL que anexo a continuación.





/**
*
Copyright (C) <2011>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include

#define FOSC 48000000
#include "simple_delay.h"

__code char __at __CONFIG1L CONFIG1L = _PLLDIV_DIVIDE_BY_5__20MHZ_INPUT__1L & _CPUDIV__OSC1_OSC2_SRC___1__96MHZ_PLL_SRC___2__1L & _USBPLL_CLOCK_SRC_FROM_96MHZ_PLL_2_1L;
//code char at __CONFIG1H CONFIG1H = _OSC_HS__USB_HS_1H & _FCMEN_OFF_1H & _IESO_OFF_1H;
__code char __at __CONFIG1H CONFIG1H = _OSC_HS__HS_PLL__USB_HS_1H & _FCMEN_ON_1H & _IESO_ON_1H;
//_FOSC_HS_1H _FOSC_HS_1H
//_OSC_HS__HS_PLL__USB_HS_1H
__code char __at __CONFIG2L CONFIG2L = _PUT_ON_2L & _BODEN_ON_2L & _BODENV_4_2V_2L & _VREGEN_ON_2L;
__code char __at __CONFIG2H CONFIG2H = _WDT_DISABLED_CONTROLLED_2H & _WDTPS_1_32768_2H;
__code char __at __CONFIG3H CONFIG3H = _CCP2MUX_RC1_3H & _PBADEN_PORTB_4_0__CONFIGURED_AS_DIGITAL_I_O_ON_RESET_3H & _LPT1OSC_ON_3H & _MCLRE_MCLR_ON_RE3_OFF_3H;
__code char __at __CONFIG4L CONFIG4L = _STVR_ON_4L & _LVP_OFF_4L & _ENHCPU_OFF_4L & _BACKBUG_OFF_4L;
__code char __at __CONFIG5L CONFIG5L = _CP_0_OFF_5L & _CP_1_OFF_5L & _CP_2_OFF_5L & _CP_3_OFF_5L;
__code char __at __CONFIG5H CONFIG5H = _CPB_OFF_5H;
__code char __at __CONFIG6L CONFIG6L = _WRT_0_OFF_6L & _WRT_1_OFF_6L & _WRT_2_OFF_6L & _WRT_3_OFF_6L;
__code char __at __CONFIG6H CONFIG6H = _WRTC_OFF_6H & _WRTB_OFF_6H;
__code char __at __CONFIG7L CONFIG7L = _EBTR_0_OFF_7L & _EBTR_1_OFF_7L & _EBTR_2_OFF_7L & _EBTR_3_OFF_7L;
__code char __at __CONFIG7H CONFIG7H = _EBTRB_OFF_7H;

//Definiciones de servos
#define SERVO1 LATBbits.LATB0
#define SERVO2 LATBbits.LATB1
#define SERVO3 LATBbits.LATB2
#define SERVO4 LATBbits.LATB3
#define SERVO5 LATBbits.LATB4
#define SERVO6 LATBbits.LATB5
#define SERVO7 LATBbits.LATB6
#define SERVO8 LATBbits.LATB7

#define CSERVO1 TRISBbits.TRISB0
#define CSERVO2 TRISBbits.TRISB1
#define CSERVO3 TRISBbits.TRISB2
#define CSERVO4 TRISBbits.TRISB3
#define CSERVO5 TRISBbits.TRISB4
#define CSERVO6 TRISBbits.TRISB5
#define CSERVO7 TRISBbits.TRISB6
#define CSERVO8 TRISBbits.TRISB7

typedef enum{false = 0, true = 1} boolean; //para definir variables booleanas

//Constantes para la definición de ventanas
const unsigned Ticks4WindowH = 0x75;
const unsigned Ticks4WindowL = 0x2F;
const unsigned Ticks4CenterH = 0x46;
const unsigned Ticks4CenterL = 0x4F;
const unsigned Ticks4MinimumH = 0x17;
const unsigned Ticks4MinimumL = 0x6F;
const unsigned Ticks4MaximumH = 0x6B;
const unsigned Ticks4MaximumL = 0xCF;
static unsigned int Ticks4NextInterruptH = 0xCF;
static unsigned int Ticks4NextInterruptL = 0x2C;


const unsigned Ticks4Window = 0x752F;
const unsigned Ticks4Minimum = 0x176F;
const unsigned Ticks4Center = 0x464F;
const unsigned Ticks4Maximum = 0x6BCF;
static unsigned int Ticks4NextInterrupt = 0xCF2C;
static unsigned int Servo_PWM[8];
static unsigned int tempom=0x0000;
static unsigned int tempo=0x0000;
static unsigned int tempol;
static unsigned int tempoh;

static unsigned int Servo_PWMH[8];
static unsigned int Servo_PWML[8];
static unsigned short Servo_Idx = 0;

boolean SERVO1_ON = false;
boolean SERVO2_ON = false;
boolean SERVO3_ON = false;
boolean SERVO4_ON = false;
boolean SERVO5_ON = false;
boolean SERVO6_ON = false;
boolean SERVO7_ON = true;
boolean SERVO8_ON = true;


boolean flag_Phase;
unsigned short j=0xFF;
unsigned int posI;

//Prototipos
void init_board(void);
void EnableTimer1Interrupt(void);
void DiSi(void);
void DiNo(void);
void Tmr1Carga(unsigned char tempoH,unsigned char tempoL);
unsigned int SelectServo(unsigned char Servo);
void turnPlus(int vueltas, unsigned char vel, unsigned char Servo);
void turnMinus(int vueltas, unsigned char vel, unsigned char Servo);


//Sección de interrupciones
static void isr_Tmr1() __interrupt 1 //Esta es una interrupcion de alta prioridad
{
PIE1bits.RCIE=0; //deshabilitamos la interrupcion del puerto serie
if(flag_Phase == 1)
{
if(Servo_Idx == 0 && SERVO1_ON) {SERVO1 = 1;}
if(Servo_Idx == 1 && SERVO2_ON) {SERVO2 = 1;}
if(Servo_Idx == 2 && SERVO3_ON) {SERVO3 = 1;}
if(Servo_Idx == 3 && SERVO4_ON) {SERVO4 = 1;}
if(Servo_Idx == 4 && SERVO5_ON) {SERVO5 = 1;}
if(Servo_Idx == 5 && SERVO6_ON) {SERVO6 = 1;}
if(Servo_Idx == 6 && SERVO7_ON) {SERVO7 = 1;}
if(Servo_Idx == 7 && SERVO8_ON) {SERVO8 = 1;}
Ticks4NextInterruptH = 0xFF - Servo_PWMH[Servo_Idx];
Ticks4NextInterruptL = 0xFF - Servo_PWML[Servo_Idx];
Tmr1Carga(Ticks4NextInterruptH,Ticks4NextInterruptL);
}

if(flag_Phase == 0)
{
if(Servo_Idx == 0 && SERVO1_ON) {SERVO1 = 0;}
if(Servo_Idx == 1 && SERVO2_ON) {SERVO2 = 0;}
if(Servo_Idx == 2 && SERVO3_ON) {SERVO3 = 0;}
if(Servo_Idx == 3 && SERVO4_ON) {SERVO4 = 0;}
if(Servo_Idx == 4 && SERVO5_ON) {SERVO5 = 0;}
if(Servo_Idx == 5 && SERVO6_ON) {SERVO6 = 0;}
if(Servo_Idx == 6 && SERVO7_ON) {SERVO7 = 0;}
if(Servo_Idx == 7 && SERVO8_ON) {SERVO8 = 0;}
Ticks4NextInterruptH = 0xFF - Ticks4WindowH;
Ticks4NextInterruptL = 0xFF - Ticks4WindowL;

if(Ticks4NextInterruptL + Servo_PWML[Servo_Idx] > 0xFF)
{
Ticks4NextInterruptL = Ticks4NextInterruptL + Servo_PWML[Servo_Idx];
Ticks4NextInterruptH = Ticks4NextInterruptH + Servo_PWMH[Servo_Idx] + 1;
}
else
{
Ticks4NextInterruptL = Ticks4NextInterruptL + Servo_PWML[Servo_Idx];
Ticks4NextInterruptH = Ticks4NextInterruptH + Servo_PWMH[Servo_Idx];
}
Tmr1Carga(Ticks4NextInterruptH, Ticks4NextInterruptL);
if(++Servo_Idx > 7 ) Servo_Idx = 0;
}
if(++flag_Phase > 1) flag_Phase = 0;

//Esta instruccion se esta ejecutando cada 13ms con un xtal de 20MHz
//LATBbits.LATB7^=1; //complementamos el valor del bit RB7
PIR1bits.TMR1IF=0; //limpiamos la bandera de interrupcion
PIE1bits.RCIE=1; //habilitamos la interrupcion del puerto serie
}



//Funcion Principal
int main(void)
{
//declaracion de variables
int i=0;
int button_down=1;
int valTimer=0;

RCONbits.IPEN=1; //interrupciones por prioridad habilitadas

init_board();


//Centrar los servos
for (i=0;i<9;i++)
{
Servo_PWMH[i] = Ticks4CenterH;
Servo_PWML[i] = Ticks4CenterL;
}

EnableTimer1Interrupt();
tempo = Ticks4Center;
tempoh = tempo & 0xFF00;
tempol = tempo & 0x00FF;
Tmr1Carga(tempoh, tempol);
posI = Ticks4Center;




while (true)
{
//Aquí va el código para si y no
if(!PORTBbits.RB0) //Termino exitosamente la actividad
{
PORTAbits.RA4 = 0;
DiSi();
// PORTAbits.RA4 = 1;
// delay_ms(20);
// PORTAbits.RA4 = 0;
// delay_ms(20);
}
if(!PORTBbits.RB1) //esta prendido el led amarillo del semaforo
{
PORTAbits.RA4 = 0;
DiNo();
}
else
{
PORTAbits.RA4 = 1; //Mientras no pase nada prende el testigo
delay_ms(20);
PORTAbits.RA4 = 0;
delay_ms(20);
}
}
return 0;
}


void init_board(void)
{
ADCON1=0x7; // PORTA used for digital I/O
TRISAbits.TRISA4=false; // configure PORTA4 como salida TESTIGO
/*Falta configurar RA0 y RA1 como entradas*/
/* Configuramos las salidas de los servomotores*/
CSERVO1 = true;
CSERVO2 = true;
CSERVO3 = true;
CSERVO4 = true;
CSERVO5 = true;
CSERVO6 = true;
CSERVO7 = false;
CSERVO8 = false;
//configurar Entradas para GRAMAKIT
TRISBbits.TRISB0 = true;
TRISBbits.TRISB1 = true;

}

void EnableTimer1Interrupt(void)
{
T1CON=1; //Timer1 preescaler 1 interno, carga de 8 bits
PIE1bits.TMR1IE=1;
INTCONbits.PEIE=1;
INTCONbits.GIE=1;
}

void DiSi(void)
{
unsigned char posicion[] = {60,90,60,90,60,90}; //posiciones en grados a mover la cabeza para decir SI
unsigned char i, DerIzq = 1;
unsigned char vel=1; //AQUI SE DEFINE LA VELOCIDAD DEL SERVO
//si quieres ver como se puede modificar este valor por medio
//de rs232, ve el archivo timer1.c


unsigned int posF;
unsigned int vueltas;

for(i = 0;i<4;i++)
{
posI = SelectServo(6); //El servo conectado a RB6
posF = 106.66 * posicion[i] + 8399;

if(posF>posI){
vueltas = posF - posI;
vueltas = vueltas / vel;
DerIzq = 1;
}
else
{
vueltas = posI - posF;
vueltas = vueltas/ vel;
DerIzq = 0;
}

if(DerIzq)
{
turnPlus(vueltas,vel,6);
}
else
{
turnMinus(vueltas,vel,6);
}
delay_ms(10);
}
}

void DiNo(void)
{
unsigned char posicion[] = {60,120,60,90}; //posiciones en grados a mover la cabeza para decir NO
unsigned char i, DerIzq = 1;
unsigned char vel=1; //AQUI SE DEFINE LA VELOCIDAD DEL SERVO
//si quieres ver como se puede modificar este valor por medio
//de rs232, ve el archivo timer1.c


unsigned int posF;
unsigned int vueltas;

for(i = 0;i<4;i++)
{
posI = SelectServo(7); //El servo conectado a RB7
posF = 106.66 * posicion[i] + 8399;

if(posF>posI){
vueltas = posF - posI;
vueltas = vueltas / vel;
DerIzq = 1;
}
else
{
vueltas = posI - posF;
vueltas = vueltas/ vel;
DerIzq = 0;
}

if(DerIzq)
{
turnPlus(vueltas,vel,7);
}
else
{
turnMinus(vueltas,vel,7);
}
delay_ms(10);
}

}

//Funcion para cargar el timer1 con valor dado por el usuario
void Tmr1Carga(unsigned char tempoH,unsigned char tempoL)
{
TMR1H=tempoH;
TMR1L=tempoL;
}


//Función para elegir el valor de tiempo que tiene un servo

unsigned int SelectServo(unsigned char Servo)
{
tempoh = Servo_PWMH[Servo];
tempo = tempoh << 8;
return (tempo | Servo_PWML[Servo]);
}


//Funcion para dar un valor incremental a la posición de un servo determinado
void turnPlus(int vueltas, unsigned char vel, unsigned char Servo)
{
int i=0;

for(i=0;i> 8;
Servo_PWMH[Servo] = tempoh;
delay_us(100);
}
}

//Funcion para dar un valor decremental a la posicion de un servo determinado
void turnMinus(int vueltas, unsigned char vel, unsigned char Servo)
{
int i=0;

for(i=0;i> 8;
Servo_PWMH[Servo] = tempoh;
delay_us(100);
}
}