Banner publicitario de PCBWay

Mejorar reforma de libreria en C

Hola a todos ., y desde ya gracias a los que respondan
Quiero cambiarlas el modo que manejo las funciones
Originalmente es con llaves ., que colocan a GND los pines/port de un microcontrolador
En el caso de la seleccion ., son 3 pin/port ., y la velocidad son 4 pin/port
Lo quiero cambiar por dos potenciometros., manejando ADC .,de 7 pin/port usaria solo 2 pin/port
Eso me permitiria migrar a un microcontrolador mas pequeño (menos pin/port)
Con la convercion de ADC y su enparejamiento a valor de 0 a 255 me funciona bien
El problema lo tengo en la funcion de selecion ya sea de funcion o velocidad
Los condicionales que elegi
C:
if
else if
Creo que son correctas ., si bien funciona ., cuando ejecuto el movimiento del potenciometro ., cambia el valor elegido pero Tambien me muestra todo los demas valores no elegidos ., cosa que con las llaves no sucede (oviamente)
Voy a mostrar solo un potenciometro (porque el otro funciona de la misma manera)
Las llaves se definen asi
C:
efecto = (0xFF -PINA);//dirección base de cálculo del patrón de DIPs
efecto = (efecto &0b111);//La resolución es bit0.bit1.bit2
La conbinacion de las pociciones de las llaves ., me da 9 valores .,
Entonces adapto esas 9 pocicones de esta manera
C:
const uint8_t Patdirec[] PROGMEM =
{
0, 2, 11, 20, 24, 31, 37, 43, 61
};

uint8_t   pasos;  //N°de pasos en el secuenciador actual
uint8_t   res;      //resolucion
uint8_t   pat_base;
uint8_t   efecto; //dirección base del paso actual
uint16_t  pat; // patron de bits
uint16or8 chs; // secuenciador

//efecto = (0xFF -PINA);//dirección base de cálculo del patrón de DIPs
//efecto = (efecto &0b111);//La resolución es bit0.bit1.bit2

     {
        
        if (potevirtual[1]>=226)
         {
        efecto=9;
         }
        else if (potevirtual[1]>=198 && potevirtual[1]<=225)
         {
        efecto=8;
         }
        else if (potevirtual[1]>=170 && potevirtual[1]<=197)
         {
        efecto=7;
         }
        else if (potevirtual[1]>=141 && potevirtual[1]<=169)
         {
        efecto=6;
         }
        else if (potevirtual[1]>=113 && potevirtual[1]<=140)
         {
        efecto=5;
         }
        else if (potevirtual[1]>=85 && potevirtual[1]<=112)
         {
        efecto=4;
         }
        else if (potevirtual[1]>=56 && potevirtual[1]<=84)
         {
        efecto=3;
         }
        else if (potevirtual[1]>28 && potevirtual[1]<55)
         {
        efecto=2;
         }
        else if (potevirtual[1]<27) // determinación de posición
         {
        efecto=1;
        }
pat_base = pgm_read_byte(&Patdirec[efecto]);//obtener la dirección base del secuenciador actual
pasos  = pgm_read_byte(&Patdirec[(efecto +1)]);//obtener la dirección base del siguiente secuenciador
pasos -= pat_base;
No veo el error de mi parte ., o capaz interpreto mal la reforma o funcionamiento del codigo
Desde ya michas gracias a que opine y perdonen la molestia
ATTE : juan
 
No termino de entender cual es tu problema, pero el potenciómetro barre todo su valor cuando lo giras, así que tal vez tengas que agregar un pulsador para confirmar el valor seleccionado en lugar de hacerlo "automáticamente" mientras giras el pote. Es la unica forma simple de evitarlo: girás y cuando llegas donde querés les das OK para que haga el cambio.
 
Hola, cuando uses múltiples selecciones con if, si se puede, no las anides, porque eso lleva a la pila de retorno a crecer descontroladamente... y en un microcontrolador suele ser chica.
Creo que estas usando un AVR, así que al menos que te pongas quisquilloso, las lecturas del ADC, salen en 10 bits, así que deberías considerar en usar variables de 16bits y el rango entre 0 y 1023.
Después de éste asunto, ya con las selecciones echas, podrías usar un switch case bla bla .... y listo!

/*selectAN.c C:\BORLAND\BCC55\BIN\bcc32.exe -e..\dosbin\selectAN.exe -oselectAN.o ..\dosSrc\selectAN.c */ #include <stdlib.h> #include <stdio.h> typedef unsigned char uint8_t; uint8_t selectSWT(uint8_t readVal) { if(readVal<=63) return 1; if((readVal>=64) && (readVal<=127)) return 2; if((readVal>=128) && (readVal<=191)) return 3; return 4; } int main(int argc, char *argv[]) { uint8_t readVal, option; readVal = atoi(argv[1]); option = selectSWT(readVal); printf("read:%u select:%u", readVal, option); return 1; } /* SALIDA: ======= C:\Users\Electro\Documents\Elect.New\DosBin>selectAN.exe 28 read:28 select:1 C:\Users\Electro\Documents\Elect.New\DosBin>selectAN.exe 67 read:67 select:2 C:\Users\Electro\Documents\Elect.New\DosBin>selectAN.exe 129 read:129 select:3 C:\Users\Electro\Documents\Elect.New\DosBin>selectAN.exe 200 read:200 select:4 C:\Users\Electro\Documents\Elect.New\DosBin>selectAN.exe 254 read:254 select:4
 
Última edición:
Hola y gracias querido profesor ., por dedicar su tiempo a enseñarme una vez mas
No termino de entender cual es tu problema, pero el potenciómetro barre todo su valor cuando lo giras, así que tal vez tengas que agregar un pulsador para confirmar el valor seleccionado en lugar de hacerlo "automáticamente" mientras giras el pote. Es la unica forma simple de evitarlo: girás y cuando llegas donde querés les das OK para que haga el cambio.
Lo de la idea del pulsador ., me parece genial ., aun que usaria un pin/port mas por cada funcion (2 en total)
Pero viendo esa idea de como confirmar la pocicion elegida ., se me acaba de ocurrir una idea
Si vemos los valores dela tabla PROGMEM
C:
const uint8_t Patdirec[] PROGMEM =
{
0, 2, 11, 20, 24, 31, 37, 43, 61
};
El primer valor coresponde a 0 que coresponden a los bits
C:
0b0000000000
Y el ultimo que es 61 que coresponde a los bits
C:
0b0111111111
Entonces ya que manejo las condicionales
Código:
if
else if
else ==1//que equivale a 0 en la tabla y que sus bits son 0b0000000000 que equivale a ninguna funcion
Que opina de mi idea profe
ATTE: juan
 
Después de éste asunto, ya con las selecciones echas, podrías usar un switch case bla bla .... y listo!
Pero eso no soluciona el problema que tiene @locodelafonola 🤷‍♂️ por que la invocación a selectSWT la hace permanentemente y cuando el pote barre sus valores le va a retornar diferentes valores no seleccionados...que es el problema que entiendo que tiene.

Que opina de mi idea profe
Que me perdí...
De que tabla hablás???

Si querés evitar una línea para el pulsador y el botón de OK....hay otra solución pero es mas "complicada"....y es usar un timer que se dispara cada vez que explorás el pote y se resetea si hubo cambio en el valor del ADC en la próxima lectura. De esa forma, si dejás quieto el pote el programa asume el estado del pote antes de que expirara el timer....pero es un bardo importante.
 
Última edición:
Que me perdí...
De que tabla hablás???
opppppppps perdon ., mil disculpas
aqui esta
Código:
const uint16_t Pattern[] PROGMEM =  

{                              

 0b0000000000,  //0 pat0: constant off

 0b0000000000,  //1

                                   

 0b0000000001,  //2 pat1: chaser

 0b0000000010,  //3

 0b0000000100,  //4

 0b0000001000,  //5

 0b0000010000,  //6

 0b0000100000,  //7

 0b0001000000,  //8

 0b0010000000,  //9

 0b0100000000,  //10

                                   

 0b0000010000,  //11 pat2: ping pong

 0b0000100000,  //12

 0b0000001000,  //13

 0b0001000000,  //14

 0b0000000100,  //15

 0b0010000000,  //16

 0b0000000010,  //17

 0b0100000000,  //18

 0b0000000001,  //19

                                   

 0b0000011000,  //20 pat3: center chase

 0b0000100100,  //21

 0b0001000010,  //22

 0b0010000001,  //23

                                   

 0b0000011000,  //24 pat4: arrow

 0b0000111100,  //25

 0b0001111110,  //26

 0b0011111111,  //27

 0b0011100111,  //28

 0b0011000011,  //29

 0b0010000001,  //30

                                   

 0b0001001001,  //31 pat5: RGB

 0b0011011011,  //32

 0b0010010010,  //33

 0b0110110110,  //34

 0b0100100100,  //35

 0b0101101101,  //36

                                   

 0b0100010001,  //37 pat6: RGB spread

 0b0101110011,  //38

 0b0001100010,  //39

 0b0011101110,  //40

 0b0010001100,  //41

 0b0110011101,  //42

                                   

 0b0001001001,  //43 pat7: RGB single change

 0b0001001011,  //44

 0b0001011011,  //45

 0b0011011011,  //46

 0b0011011010,  //47

 0b0011010010,  //48

 0b0010010010,  //49

 0b0010010110,  //50

 0b0010110110,  //51

 0b0110110110,  //52

 0b0110110100,  //53

 0b0110100100,  //54

 0b0100100100,  //55

 0b0100100101,  //56

 0b0100101101,  //57

 0b0101101101,  //58

 0b0101101001,  //59

 0b0101001001,  //60

                                   

 0b1111111111   //61 (dummy)

};
 
Hola Juan.
No estoy viendo cual es el contexto de uso de esa tabla, pero si tenes una opción que es "ninguna función" lo mismo no te va a servir con los if..else por que a medida que giras el pote el valor del ADC va entrando en algunos rangos de valores que van a activar opciones indeseadas.
Yo creo que la mas fácil de todas es el pulsador de confirmación, y si no podés usar o no tenes un pin extra para el pulsador...la otra solución sería activar un timer de 1 segundo (ponele) cuando cambie el valor del ADC. Una vez iniciado el timer lo reseteás si vuelve a haber un cambio del ADC antes del que el tiempo expire. Cuando el timer expire luego de 1 segundo sin cambios en el ADC entonces la ISR aplica la función correspondiente al ultimo valor del ADC.
En resumen: vos girás el potenciómetro y el valor del ADC va cambiando, y si lo dejás quieto...luego de 1 segundo se activa la opción correspondiente. Esto requiere jugar un rato con el tiempo del timer hasta que te guste como opera, y tambien jugar con el rango de cambio del ADC antes del reset del timer para que no te moleste el ruido...
 
hola y disculpe no haber aportado toda la informacion
Hola Juan.
No estoy viendo cual es el contexto de uso de esa tabla, pero si tenes una opción que es "ninguna función" lo mismo no te va a servir con los if..else por que a medida que giras el pote el valor del ADC va entrando en algunos rangos de valores que van a activar opciones indeseadas.
Eso....... eso........ eso....... eso........ eso........ diria el chavo del 8
Eso es exactamente lo que me sucede (dificil de explicar para mi ...ja ja ja ) ., y estoy probando en lo fisico ., NO simulacion
Hola Juan.
La otra solución sería activar un timer de 1 segundo (ponele) cuando cambie el valor del ADC. Una vez iniciado el timer lo reseteás si vuelve a haber un cambio del ADC antes del que el tiempo expire. Cuando el timer expire luego de 1 segundo sin cambios en el ADC entonces la ISR aplica la función correspondiente al ultimo valor del ADC.
En resumen: vos girás el potenciómetro y el valor del ADC va cambiando, y si lo dejás quieto...luego de 1 segundo se activa la opción correspondiente. Esto requiere jugar un rato con el tiempo del timer hasta que te guste como opera, y tambien jugar con el rango de cambio del ADC antes del reset del timer para que no te moleste el ruido...
¿¿¿ y como seria eso del timeren el codigo ???? tambien podria ser un "delays" aca no hay problema por su uso
Muchas gracias por brindarme su tiempo
ATTE : juan
 
¿¿¿ y como seria eso del timer en el codigo ???? tambien podria ser un "delays" aca no hay problema por su uso
No se me ocurre como sería con un delay, pero con una interrupción es mas simple.
Solo necesitás una función que lea el ADC y detecte cuando cambia la lectura. Cuando cambia --> se supone que alguien gira el pote y activas una interrupcion del timer para dentro de un segundo. Seguís leyendo el ADC y si detectas que vuelve a cambiar, restableces el valor del timer para que cuente un segundo desde cero, y así siguiendo mientras cambie. Si no vuelve a cambiar, al cumplirse el segundo de tiempo la rutina de interrupción se desinstala, captura el valor del ADC, calcula la función que corresponde, la activa y finaliza. Así queda todo preparado para el proximo movimiento del pote.
Obviamente vas a necesitar leer periódicamente el estado del ADC (=valor del pote) para ver si alguien lo gira o nó, guardando siempre el ultimo valor leído y definiendo un intervalo de valores que permitan detectar el cambio y dar inmunidad al ruido al sistema (por ejemplo si la última lectura es igual a la anterior +/- 2% no hay que darle bola por que puede ser ruido, pero si cambia mas de eso puede ser por que alguien gira el pote y se debe dar inicio a todo lo explicado desde el principio).
 
Atrás
Arriba