Como contei num
post anterior, recuperei dois potenciômetros motorizados da
Alps (RK168). Na tentativa de encontrar uma utilidade para eles montei um circuito e escrevi algumas linhas de código para memorizar a posição do potenciômetro. Fica mais fácil de entender vendo o vídeo do circuito em funcionamento:
O circuito ficou assim:
Além do potenciômetro, reaproveitei também o controlador de motor
BA6208 da sucata. O microcontrolador é um MC9S08QG8 da Freescale. O ideal seria um microcontrolador com alimentação de 5V que é a mesma tensão do motor do potenciômetro e do driver, mas como eu tinha alguns QG8 sobrando e a placa
DEMO9S08QG8 (grava e debuga) optei por ele. A alimentação próxima a 3,3V foi conseguida a partir do 5V passando pelos três diodos 1N4148 em série.
O botão "MEM" grava o valor atual do potenciômetro na memória. O botão "MR" recupera o valor, levando o cursor do potenciômetro para a posição memorizada. O código que faz isso não tem muito segredo:
MotorCtrl_PutVal(MOTOR_STDBY); /* Desliga o motor */
for(;;)
{
(void)AD1_Measure(0); /* Inicia medida no conversor AD */
Key = Teclas_GetVal(); /* Le as teclas */
/* Verifica se uma tecla foi pressionada */
if (Key == MEM_KEY) /* Tecla de memoria? */
{
Mem_Value = AD_Value; /* Memoriza novo valor */
if (Mem_Value > MAX_VALUE) /* Novo valor eh maior que o valor maximo permitido? */
{
Mem_Value = MAX_VALUE; /* Nao passa do valor maximo permitido */
}
if (Mem_Value < MIN_VALUE) /* Novo valor eh menor que o valor minimo permitido? */
{
Mem_Value = MIN_VALUE; /* Nao passa do valor minimo permitido */
}
Key = NO_KEY; /* Nenhuma chave pressioanada */
}
else if (Key == RM_KEY) /* Tecla de recuperar? */
{
if (Mem_Value > AD_Value) /* Verifica qual eh o valor maior */
{
while (Mem_Value >= AD_Value) /* Enquanto nao ultrapassar o valor memorizado */
{
(void)AD1_Measure(0); /* Inicia medida no conversor AD */
MotorCtrl_PutVal(MOTOR_CW); /* Gira motor no sentido horario */
}
/* Talvez nao seja necessario freiar o motor, mas... */
MotorCtrl_PutVal(MOTOR_BRAKE); /* Freia o motor */
Cpu_Delay100US(1000); /* Espera 100ms */
MotorCtrl_PutVal(MOTOR_STDBY); /* Desliga o motor */
}else
{
while (AD_Value >= Mem_Value) /* Enquanto nao ultrapassar o valor memorizado */
{
(void)AD1_Measure(0); /* Inicia medida no conversor AD */
MotorCtrl_PutVal(MOTOR_CCW); /* Gira o motor no sentido anti-horario*/
}
/* Talvez nao seja necessario freiar o motor, mas... */
MotorCtrl_PutVal(MOTOR_BRAKE); /* Freia o motor */
Cpu_Delay100US(1000); /* Espera 100ms */
MotorCtrl_PutVal(MOTOR_STDBY); /* Desliga o motor */
}
Key = NO_KEY; /* Nenhuma chave pressionada */
}
}
O projeto completo com todo o código fonte
pode ser baixado aqui (para CodeWarrior 6.3). Usei o Processor Expert do CodeWarrior pra facilitar as coisas e ganhar tempo. (Código sob licença
WTFPL)
Trata-se de um loop infinito que fica checando se alguma tecla foi pressionada. A comparação para encontrar a posição memorizada foi feita apenas checando se a posição atual é "maior ou igual" ou "menor ou igual" que a memorizada. Isso causa um erro na posição final, ao parar o motor, mas nada que ultrapasse os 5%. Como o circuito foi montado apenas como uma prova de conceito não me preocupei muito com isso, já que pode ser melhorado no código depois.
O grande problema deste circuito é que se perde uma das pastilhas do potenciômetro para fazer o sensor de posição. Já não serve para controlar volume num amplificador estéreo, por exemplo. Até pensei em colocar mais um outro pot motorizado, seguindo o valor do outro e/ou outras firulas, mas preciso pesar se vale a pena fazer isso e se eu realmente vou usar.