Plataforma Robótica
- Ivan Mauricio Rodríguez 1
- Andrés Mauricio Rodríguez 1
- Gerson Darío Piraquive 1
Contents |
[edit] Calificación
| Porcentaje | Presentación 20% | Informe 30% | Funcionamiento 50% |
|---|---|---|---|
| 1 Entrega 10% | 1 | 1 | 1 |
| 2 Entrega 30% | 2 | 2 | 2 |
| 3 Entrega 30% | 2 | 2 | 2
|
| 4 Entrega 30% | 5 | 5 | 5 |
[edit] Proyecto
Para el proyecto final de la materia de Sistemas Embebidos, se trabajará con la tarjeta SIE (antes llamada SAKC). Esta tarjeta cuenta principalmente con un SoC de Ingenic Semiconductor Jz4725 y una FPGA Xilinx Spartan 3E XC3S500E, además de varios periféricos que la hacen una solución multimedia ́óptima para productos de MP3, MP4 y dispositivos móiles portables. El procesador del SoC es un XBurst core de 32 bits, el cual utiliza un conjunto de instrucciones SIMD y RISC, en combinación con una unidad de post-procesamiento de video.
[edit] Descripción
El proyecto a realizar es una brazo mecánico que contará con servomotores para controlar el ángulo de posición de cada articulación. Este brazo tendrá tres grados de libertad los cuales se pueden interpretar como hombro, codo y pinza, utilizado para diferentes fines como agarrar objetos, lanzárlos, manipularlos, etc. Como aplicación específica el brazo tomará objetos de una banda transportadora y los colocará en otro lugar. Para poder ubicar el objeto, se colocará un sensor de proximidad en un punto determinado y cuando éste lo detecte, la banda parará su movimiento
Para su funcionamiento, los motores y servomotores necesitan una etapa de potencia, puesto que necesitan mucha corriente. Se usará un convertidor DC-DC y optoacopladores para ponerle protección a los circuitos utilizados. Para el movimiento de la banda transportadora se usarán motores de corriente continua controlados por un puente H.
Con el fin de tener un control más práctico de los servomotores, se colocarán tres potenciómetros para aumentar o reducir la tensión que llega a las entradas análogas en los terminales del ADC. Esta tensión corresponderá a un ciclo útil del PWM.
[edit] Funciones
La plataforma tendrá las siguientes funciones:
- Tomar un objeto.
- Arrojar el objeto.
- Controlar el movimiento de cada articulación del brazo.
- Tomar objetos de una banda transportadora y desplazarlos.
[edit] Herramientas Hardware
- Tarjeta SIE
- Power Driver
Este driver nos permitirá controlar los motores de desplazamiento de la plataforma en las dos direcciones y además nos proporciona una parada rápida, que frena inmediatamente el motor.
- Convertidores DC-DC
Los convertidores nos servirán para alimentar los motores y los servomotores, haciendo una función de step-up de tensión de 4.5V a 6V. En este caso la corriente de salida es aproximadamente 500 mA. Si se considera que cada motor/servomotor consume un valor máximo 200 mA, es decir, exigiéndolo por completo, estos convertidores nos sirven para nuestro propósito.
- Servomotores (HiTec 311, Futaba S3006, TowerPro SMG995R)
El rango de ciclos útiles de los servos es 193 a 238 para la base, 222 a 234 para el codo y 216 a 225 para la pinza.
- Optoacopladores (MOCD213)
[edit] Herramientas Software
- Lua
Lua es un poderoso lenguaje "embebido". Esto significa que Lua no es un paquete autónmo, sino una librería que puede ser "enlazada" con otras aplicaciones para incorporar facilidades de Lua en estas aplicaciones.
Lua posee también un intérprete autónomo que ejecuta instrucciones (chunks) en tiempo real, interactuando con el usuario. De esta manera se van a controlar los movimientos del brazo mecánico.
- Xilinx ISE WebPack
Herramienta para crear los módulos hardware en la FPGA de la SIE.
- KiCAD
Con esta herramienta se diseñó el circuito impreso de montaje superficial.
[edit] Hardware
Para la plataforma robotica el componente de hardware consistira basicamente en:
1. PWM (pulse width modulation). Técnica mendiante la cual se modifica el ciclo de trabajo de una señal periodica para controlar la cantidad de energía que se envia a una carga.
2. Conversor ADC (Analog to digital converter). Conversión de una señal de entrada analogica en valor binario, para poderla manipular en los circuitos digitales. Las señales a convertir son las entregadas por cada uno de los sensores de proximidad (TCRT1000)
3. Controlador del integrado HIP4020 (Full Bridge Power Driver). Driver de potencia especialmente diseñado para motores DC pequeños.
[edit] Comunicación Procesador-Periféricos
[edit] Periféricos
Se usarán 5 periféricos determinados por el componente hardware descrito anteriormente, es decir, 3 módulos PWM, 1 controlador del ADC y 1 controlador del driver de motor.
[edit] PWM como periférico en la FPGA
Este periférico se encarga de controlar los servomotores dispuestos para el brazo.
Como se observa en la figura anterior, este recibe 8 bits de información del procesador (sram_data) que determinan el ciclo útil de la señal periódica saliente (pwm), el periodo de esta señal esta determinado por un parámetro interno del modulo llamado temp1.
El diagrama de flujo se muestra a continuación en donde se explica el comportamiento del periferico.
El modulo mostrado a continuación es la segunda versión del controlador de los 3 periféricos de pwm usados para el control de los servomotores.
`timescale 1ns / 1ps
module pwm(pwm1, pwm2, pwm3,
wdBus, we, cs,
reset, clk);
parameter B = (7);
input clk, we, reset;
input [3:0] cs;
input [B:0] wdBus;
output pwm1, pwm2, pwm3;
//PWMparameter temp = 500000;
reg [25:0] temp1, temp2, temp3;
reg [25:0] counter1, counter2, counter3;
reg ck1, ck2, ck3;
//initializeinitialbegincounter1 = 26'b0;
counter2 = 26'b0;
counter3 = 26'b0;
temp1 = 26'b0;
temp2 = 26'b0;
temp3 = 26'b0;
ck1=0;
ck2=0;
ck3=0;
end//--------------------------------------------------------------------------//PWM peripherial1always @(negedge clk)
beginif (we & cs[1] & wdBus != temp1) temp1 = wdBus * temp / 256;
endalways @(posedge clk)
begincounter1 = counter1 + 1;
if (counter1 <= temp1)
ck1 = 1'b1;
elsebeginif(counter1 == temp)
counter1 = 26'b0;
elseck1 = 1'b0;
endend//PWM peripherial2always @(negedge clk)
beginif (we & cs[2] & wdBus != temp2) temp2 = wdBus * temp / 256;
endalways @(posedge clk)
begincounter2 = counter2 + 1;
if (counter2 <= temp2)
ck2 = 1'b1;
elsebeginif(counter2 == temp)
counter2 = 26'b0;
elseck2 = 1'b0;
endend//PWM peripherial3always @(negedge clk)
beginif (we & cs[3] & wdBus != temp3) temp3 = wdBus * temp / 256;
endalways @(posedge clk)
begincounter3 = counter3 + 1;
if (counter3 <= temp3)
ck3 = 1'b1;
elsebeginif(counter3 == temp)
counter3 = 26'b0;
elseck3 = 1'b0;
endendassign pwm1 = ck1;
assign pwm2 = ck2;
assign pwm3 = ck3;
endmodule
La frecuencia de la señal PWM es de 100 Hz. Escogimos esta frecuencia porque al hacer pruebas con los servos, éstos no pedían mucha corriente (alrededor de 400 mA), y si subíamos la frecuencia hasta 150 Hz se cuadruplicaba la corriente necesitada. El ciclo útil de la señal se define por el vector de 8 bits sram_data.
A continuación se muestra la simulación para este módulo,
[edit] H_BRIDGE
Para el movimiento de la banda de la plataforma robótica se han dispuesto dos moto-reductores, cada uno es controlado a través de los driver de potencia Hip4020. Para el manejo de estos integrados se ha dispuesto este periférico.
El integrado recibe 3 señales de entrada (Brake, Direction y Enable) con las cuales controla la dirección del motor conectado a este. Estas tres señales son aportadas por el procesador (sram_data).
Aunque el comportamiento de este no es muy complicado, se expresa a continuación a través de un diagrama de flujo.
La descripción de hardware es la siguiente:
`timescale 1ns / 1ps
module H_BRIDGE(brake, direction, enableM, wdBus, we, cs,reset, clk
);
parameter B = (7);
input clk, we, reset, cs;
input [B:0] wdBus;
output brake, direction, enableM;
reg [B:0] temp;
reg brakeB, directionB, enableB;
initialbegintemp = 8'b0;
brakeB = 0;
directionB = 0;
enableB = 0;
endalways @(negedge clk)
beginif (we & cs & wdBus != temp) begin
temp = wdBus;
endendalways @(posedge clk)
beginbrakeB = temp[0];
directionB = temp[1];
enableB = temp[2];
endassign brake = brakeB;
assign direction = directionB;
assign enableM = enableB;
endmodule
[edit] ADC
Se utilizó el controlador del ADC del ejemplo descrito en Scope. Este controlador se basa en el siguiente diagrama de tiempos.
[edit] Diagramas de Bloques
[edit] Esquemáticos y PCB
[edit] Software
[edit] Usando Lua
Como se mencionó en secciones anteriores, se va a usar Lua para ejecutar las acciones en tiempo real y llamar a las APIs escritas en C. Para comenzar implementamos el controlador del periférico PWM. Se tomó como referencia el ejemplo descrito en Lua_Blink_LED. TODAS las funciones utilizadas se encuentran repartidas en los archivos jz47xx_gpio.c, Control.c, ADCw.c, sram_gpio_wrap.c. jz_adc_peripherial.c es el mismo del usado en el ejemplo de Scope/es que toma el valor del puntero cuando se hace el mapeo de direcciones de la FPGA. En peripherials.lua se encuentran las funciones relacionadas con las rutinas.
Funciones en jz47xx_gpio.c
voidjz_belt (int stop)
{JZ_REG *virtual4;
virtual4 = ADCBuffer + 0x700;
if (stop==1)
{virtual4[0]=5;
usleep(500000);
}else{virtual4[0]=4;
usleep(500000);
}}voidjz_mapping (int duty, int motor)
{JZ_REG *virtual2, *virtual3, *virtual1;
switch(motor)
{case 1: virtual1 = ADCBuffer + 0x200;
virtual1[0] = duty;
break;
case 2: virtual2 = ADCBuffer + 0x400;
virtual2[0] = duty;
break;
default: virtual3 = ADCBuffer + 0x600;
virtual3[0]=duty;
break;
}}
- jz_belt() se encarga de escribir en el periférico del puente H un valor alto o un valor bajo para que el motor gire o deje de girar.
- jz_mmaping() escribe el valor del ciclo útil en el servomotor deseado.
Funciones en Control.c
#define ref 245#define inc 37#define inc2 55#define inc3 70int control1(float a)
{int b=215;
int a_ant = 0;
if(a <= a_ant+20) a=a_ant;
else if(a<=ref)b=193;
else if(a>ref && a<=(ref+inc)) b=195;
else if(a>(ref+inc) && a<=(ref+(inc*2))) b=197;
else if(a>(ref+inc*2) && a<=(ref+(inc*3))) b=199;
else if(a>(ref+inc*3) && a<=(ref+(inc*4))) b=201;
else if(a>(ref+inc*4) && a<=(ref+(inc*5))) b=203;
else if(a>(ref+inc*5) && a<=(ref+(inc*6))) b=205;
else if(a>(ref+inc*6) && a<=(ref+(inc*7))) b=207;
else if(a>(ref+inc*7) && a<=(ref+(inc*8))) b=209;
else if(a>(ref+inc*8) && a<=(ref+(inc*9))) b=211;
else if(a>(ref+inc*9) && a<=(ref+(inc*10))) b=213;
else if(a>(ref+inc*10) && a<=(ref+(inc*11))) b=215;
else if(a>(ref+inc*11) && a<=(ref+(inc*12))) b=217;
else if(a>(ref+inc*12) && a<=(ref+(inc*13))) b=219;
else if(a>(ref+inc*13) && a<=(ref+(inc*14))) b=221;
else if(a>(ref+inc*14) && a<=(ref+(inc*15))) b=223;
else if(a>(ref+inc*15) && a<=(ref+(inc*16))) b=225;
else if(a>(ref+inc*16) && a<=(ref+(inc*17))) b=227;
else if(a>(ref+inc*17) && a<=(ref+(inc*18))) b=229;
else if(a>(ref+inc*18) && a<=(ref+(inc*19))) b=231;
else if(a>(ref+inc*19) && a<=(ref+(inc*20))) b=233;
else if(a>(ref+inc*20) && a<=(ref+(inc*21))) b=235;
else if(a>(ref+inc*21)) b=238;
a_ant=a;
return b;
}int control2(float a)
{int b=225;
int a_ant = 0;
if(a <= a_ant+inc2) a=a_ant;
else if(a<=ref)b=220;
else if(a>ref && a<=(ref+inc)) b=221;
else if(a>(ref+inc2) && a<=(ref+(inc2*2))) b=222;
else if(a>(ref+inc2*2) && a<=(ref+(inc2*3))) b=223;
else if(a>(ref+inc2*3) && a<=(ref+(inc2*4))) b=224;
else if(a>(ref+inc2*4) && a<=(ref+(inc2*5))) b=225;
else if(a>(ref+inc2*5) && a<=(ref+(inc2*6))) b=226;
else if(a>(ref+inc2*6) && a<=(ref+(inc2*7))) b=227;
else if(a>(ref+inc2*7) && a<=(ref+(inc2*8))) b=228;
else if(a>(ref+inc2*8) && a<=(ref+(inc2*9))) b=229;
else if(a>(ref+inc2*9) && a<=(ref+(inc2*10))) b=230;
else if(a>(ref+inc2*10) && a<=(ref+(inc2*11))) b=231;
else if(a>(ref+inc2*11) && a<=(ref+(inc2*12))) b=233;
else if(a>(ref+inc2*12) && a<=(ref+(inc2*13))) b=234;
else if(a>(ref+inc2*13)) b=235;
a_ant=a;
return b;
}int control3(float a)
{int b=220;
int a_ant = 0;
if(a <= a_ant+inc3) a=a_ant;
else if(a<=ref)b=215;
else if(a>ref && a<=(ref+inc)) b=216;
else if(a>(ref+inc) && a<=(ref+(inc*2))) b=217;
else if(a>(ref+inc*2) && a<=(ref+(inc*3))) b=218;
else if(a>(ref+inc*3) && a<=(ref+(inc*4))) b=219;
else if(a>(ref+inc*4) && a<=(ref+(inc*5))) b=220;
else if(a>(ref+inc*5) && a<=(ref+(inc*6))) b=221;
else if(a>(ref+inc*6) && a<=(ref+(inc*7))) b=222;
else if(a>(ref+inc*7) && a<=(ref+(inc*8))) b=223;
else if(a>(ref+inc*8) && a<=(ref+(inc*9))) b=224;
else if(a>(ref+inc*9)) b=225;
a_ant=a;
return b;
}
- control1(), control2() y control3() envían un ciclo útil de acuerdo a una tensión DC que es cambiada por los potenciómetros.
Funciones en ADCw.c
void init()
{BUFFER_OFFSET = 8;
ADC_SPI_CLKDIV=ADC_SPI_CLKDIV_MAX;
BUFFER_LEN=16;
MUX_CHANNELS =0;
ADCBuffer = jz_adc_init();
for (int i = 0; i < 512; i++)
{ADCBuffer[i] = 0x00000000;
}adcConfig(ADC_CMD_SET_SPI_CLKDIV);
adcConfig(ADC_CMD_SET_FAST_CONV);
}float ADC(int servo)
{int a,b,c,d=0;
switch (servo)
{case 1:
printf("\nTomando muestras potenciometro 1...\n");
adcConfig(ADC_CMD_SET_CHANNEL3);
adcConfig(ADC_CMD_READ_CHANNEL3);
break;
case 2:
printf("\nTomando muestras potenciometro 2...\n");
adcConfig(ADC_CMD_SET_CHANNEL1);
adcConfig(ADC_CMD_READ_CHANNEL1);
break;
case 3:
printf("\nTomando muestras potenciometro 3...\n");
adcConfig(ADC_CMD_SET_CHANNEL2);
adcConfig(ADC_CMD_READ_CHANNEL2);
break;
case 4:
printf("\nTomando muestras del sensor...\n");
adcConfig(ADC_CMD_SET_CHANNEL0);
adcConfig(ADC_CMD_READ_CHANNEL0);
break;
default:
printf("\nError...\n");
}for(int i=BUFFER_OFFSET; i< BUFFER_LEN/2+BUFFER_OFFSET; i++)
{a=ADCBuffer[i]<<16;
b=a>>16;
c=ADCBuffer[i]>>16;
d=d+b+c;
}d=d/(BUFFER_LEN/2+BUFFER_OFFSET);
fflush (stdout);
return d;
}void adcConfig(uchar CMD)
{ADCBuffer[0] = (((MUX_CHANNELS<<6) + CMD)<<24) + \
((BUFFER_LEN+BUFFER_OFFSET*2) << 8) + \
(ADC_SPI_CLKDIV);
while(adcCheckBufferFull()) usleep(10000);
}int adcCheckBufferFull()
{return ADCBuffer[0]&0x20000000;
}
- init() inicializa al ADC con un velocidad de reloj mínima (97.65 kHz) y lo configura en conversión rápida.
- ADC() toma muestras de un determinado canal, que puede corresponder a algún potenciómetro o al sensor de proximidad y saca un valor promedio de esas muestras.
- adcConfig() selecciona un canal de toma o una configuración del ADC y adcCheckBuffer() revisa la capacidad del Buffer.
El archivo sram_gpio_wrap.c es fundamental para el uso de Lua porque contiene el registro de las funciones descritas anteriormente. Así mismo, en el registro de esas funciones se agregaron algunas líneas de código para ampliar su funcionalidad.
static int init_wrap(lua_State *L){
init();
return 0;
}static int take_sample_wrap(lua_State *L){
double color=ADC(4);
lua_pushnumber(L, color);
return 1;
}static int jz_mmap_wrap(lua_State *L){
int duty = luaL_checkint(L, 1);
int motor= luaL_checkint(L, 2);
jz_mapping(duty,motor);
return 0;
}static int usleep_wrap(lua_State *L){
usleep(500000);
return 0;
}static int control_wrap(lua_State *L){
int duty1_ant=0;
int duty2_ant=0;
int duty3_ant=0;
for(;;){
int duty1 = control1(ADC(1));
printf("Servo 1 --> %d",duty1);
int duty2 = control2(ADC(2));
printf("Servo 2 --> %d",duty2);
int duty3 = control3(ADC(3));
printf("Servo 3 --> %d",duty3);
usleep(10000);
if(duty1 != duty1_ant && duty1 < duty1_ant+10)
jz_mapping(duty1,1);
if(duty2 != duty2_ant)
jz_mapping(duty2,2);
if(duty3 != duty3_ant)
jz_mapping(duty3,3);
duty1_ant = duty1;
duty2_ant = duty2;
duty3_ant = duty3;
}return 0;
}static int jz_belt_wrap(lua_State *L){
int stop = luaL_checkint(L,1);
jz_belt(stop);
return 0;
}static const struct luaL_reg functions[] = {
{"init",init_wrap},
{"usleep",usleep_wrap},
{"control",control_wrap},
{"sample",take_sample_wrap},
{"mmap",jz_mmap_wrap},
{"belt",jz_belt_wrap},
{ NULL, NULL}
};
int luaopen_gpio(lua_State *L) {
luaL_newmetatable(L, metaname);
luaL_register(L, "gpio", functions);
return 1;
}
- init_wrap() ejecuta init().
- take_sample_wrap() toma muestras del sensor de proximidad y retorna el promedio de esas muestras.
- jz_mmap_wrap() toma los dos argumentos del stack de lua y los ejecuta jz_mmap().
- usleep_wrap() ejecuta la función usleep() de la librería time.h.
- control_wrap() se encarga de usar control(1), control(2) y control3() en un ciclo infinito para controlar los servomotores con los potenciómetros.
- belt_wrap() detiene la banda dependiendo del valor del argumento que se escribe en el stack.
- luaL_reg registra las funciones con un nombre determinado para poderlas trabajar.
- luaL_register () crea un identificador "gpio" para llamar las funciones registradas en la estructura.
peripherials.lua se muestra a continuación,
package.cpath = "./?.so"
require "gpio"
function Initial ()
gpio.mmap(215,1) usleep()
gpio.mmap(225,2) usleep()
gpio.mmap(225,3) usleep()
belt(1)
endfunction init()
gpio.init()
endfunction PWM (duty,motor)
gpio.mmap(duty,motor)
endfunction usleep()
gpio.usleep()
endfunction rutine_white()
Initial()
PWM(234,2) usleep() PWM(218,3) usleep()
PWM(225,2) usleep() PWM(225,1) usleep() PWM(237,1) usleep()
PWM(234,2) usleep() PWM(223,3) usleep() PWM(225,2) usleep() PWM(225,1)
endfunction rutine_black()
Initial()
PWM(234,2) usleep() PWM(218,3) usleep()
PWM(225,2) usleep() PWM(210,1) usleep() PWM(195,1) usleep()
PWM(234,2) usleep() PWM(223,3) usleep() PWM(225,2) usleep() PWM(210,1)
endfunction belt(stop)
gpio.belt(stop)
endfunction rutine()
color=gpio.sample()
print("Taking samples from Lua",color)
if color < 7 then
belt(0)
elseif color > 70 then
belt(1)
rutine_white()
elsebelt(1)
rutine_black()
endendfunction cycle()
for i=1,1000000 do
rutine()
endendfunction ctrl()
gpio.control()
endinit()
Initial()
Initial()
- Initial() coloca los servos en una posición inicial.
- PWM() escribe el ciclo útil en un servo determinado.
- cycle() ejecuta en un tiempo casi indefinido la rutina de tomar el objeto de la banda transportadora y dependiendo del color ponerlo en una determinada posición.
- ctrl() ejecuta el ciclo infinito de escribir la posición en los servos con los potenciómetros.
Primero se hace init() y luego Initial().
Todas estas funciones registradas y descritas en peripherials.lua son llamadas en el modo interactivo de lua con la función dofile("peripherials.lua").
[edit] Driver
El driver creado es para el control de los 3 Servomotores a través de un ciclo útil enviado por este mismo. Este tiene el mismo concepto y en general el mismo funcionamiento que lo hecho en espacio de usuario. Sin embargo hay que tener en cuenta que en este caso no se realizo un mapeo virtual de la memoria física, sino que los datos se envían directamente a esa dirección física (FPGA_BASE = 0xb5000000).
En primera instancia cuando el driver sea cargado se debe configurar el CS2 para el correcto funcionamiento
#define CS2_PIN JZ_GPIO_PORTB(26)
jz_gpio_set_function(CS2_PIN, JZ_GPIO_FUNC1);
Luego se procede a inicializar cada uno de los servomotores con las posiciones definidas.
outb(215,FPGA_BASE + 0x800);
outb(225,FPGA_BASE + 0x1000);
outb(220,FPGA_BASE + 0x1800);
Después de realizar esto el modulo queda cargado.
La escritura en el mismo consta de ingresar el ciclo útil seguido de una coma y el servomotor al cual enviarle el dato ( 225,1 ). La función de escritura del driver se muestra a continuación:
static ssize_tdevice_write(struct file *filp, const char *buff, size_t count, loff_t * off)
{int cmd = buff[0]-48;
int cmda = buff[1]-48;
int cmdb = buff[2]-48;
int cmdc = buff[3]-48;
int cmdd = buff[4]-48;
int cmde = 0;
int dir;
if(cmdc == -4)
{cmde = cmd*100 + cmda*10 + cmdb;
printk(KERN_INFO "Dutyout %d Servo %d\n", cmde, cmdd);
dir = cmdd*0x800;
outb( cmde , FPGA_BASE + dir);
}return 1;
}
Se resta el numero 48 debido a que esta función recibe una cadena de caracteres y como se esta enviando un numero, este es tomado en código ASCII. Se usan 5 registros para tomar cada uno de los "numeros" recibidos en la función, si se ingresa correctamente el dato el cuarto registro sera el carácter ',' (44 en ASCII) entrando en el condicional y enviando el ciclo útil al servomotor escogido.
Un ejemplo del uso de esta función se muestra a continuación (el nodo de comunicación debe estar creado mknod /dev/pwm c 252 0)
$ echo '215,1'>/dev/pwm
De este modo se enviara un ciclo útil de 215 al servomotor 1. También es posible enviar datos a cada servo simultáneamente.
$ echo '215,1 230,2 216,3' > /dev/pwm
En este caso se enviara un ciclo util de 215 al servo 1, 230 al servo 2 y 216 al servo 3.
[edit] Cronograma de Actividades
- Semana 5. Propuesta del Proyecto.
- Semana 6. Adquisición de la tarjeta SIE y pedido del gripper mecánico. Creación de la imagen del kernel de Linux.
- Semana 7. Verificación PCB.
- Semana 8. Verificación de subcircuitos (PWM, Proximidad, Convertidor DC-DC, etc.)
- Semana 9. Montaje PCB.
- Semana 10. Driver PWM. Driver SPI. Driver H-Bridge.
- Semana 13. Comuncación del ADC.
- Semana 14. Lógica Sensores de Proximidad.
- Semana 15. Creación API's.
- Semana 16. Verificación y Pruebas
[edit] Análisis Económico
[edit] Costo de elaboración prototipo
- Materiales.
- Sie..........................................$ 200000
- Pcb.........................................$ 120000
- Piezas en acrilico.....................$ 45000
- Servos.....................................$ 80000
- Gripper más servo....................$ 60000
- Componentes electrónicos........$ 90000
- Moto-reductores.......................$ 60000
- Otros.......................................$ 50000
- Total Materiales directos............$ 705000
- Mano de obra.
- Tiempo semanal de labores.................... 15 Horas
- Semanas de labores.............................. 12 Semanas
- Costo hora laboral por desarrollador......... $ 40000
- Desarrolladores...................................... 3
- Total Mano de obra directa.......................$ 21´600000
- Total elaboración del prototipo............$ 22´305000
[edit] Costo de producción en masa (100 dispositivos)
- Materiales.
- Pcb.........................................$ 582750
- Piezas en acrilico.....................$ 2´250000
- Servos.....................................$ 4´000000
- Gripper más servo....................$ 3´000000
- Componentes electrónicos........$ 4´500000
- Moto-reductores.......................$ 3´000000
- Otros......................................$ 1´250000
- Total Materiales directos...........$ 18´582750
- Costo desarrollo inicial.................... $ 22´305000
- Costo mano de obra ensamble ........$ 2´000000
- Total elaboración 100 dispositivos.... $ 42´887750