Error en funcion (SOLUCIONADO)

Tengo conectado un DIP Switch de 4 posiciones para configurar la direccion de cada modulo. Encontre este codigo pero me da error en la funcion y no veo el problema.
Lo que entiendo que hace es leer cada entrada y mover el valor 0-1 de cada entrada a su posicion en la variable DIPValue pero esta linea no la entiendo ** j += 1«(numPins?—?1?—?i);**

int DipPins[] = {  2, 3, 4, 5}; //DIP Switch Pins

void setup()
{
  Serial.begin(9600);
  for(int i = 0; i <= 4; i++)
  {
    pinMode(DipPins[i], INPUT);       
   
  }
  delay(100);
}

void loop()
{
  byte DIPValue = readDIP(DipPins, 4);
  Serial.println(DIPValue, BIN);
  delay(1000);
}

//Read binary from DIP switches
byte readDIP(int* dipPins, int numPins)
{
  byte j = 0;
  //byte j;
  //Get the switches state
  for(int i = 0; i < numPins; i++)
  {
    if (!digitalRead(dipPins[i]));
    {
    j += 1«(numPins?—?1?—?i);
    }
  }
  return j; //Return result
}

Saludos.

Buenas Flico

byte readDIP(int* dipPins, int numPins)
{
  byte j = 0;
  //byte j;
  //Get the switches state
  for(int i = 0; i < numPins; i++)
  {
    if (!digitalRead(dipPins[i]));
    {
    j += 1«(numPins?—?1?—?i);
    }
  }
  return j; //Return result
}

lo que hace la función en el caso que nos ocupa, un DIPswich de 4
En una primera vuelta i=0, lo que hace es leer el pin 2, en caso de valer 1, hace la linea que no entiendes, que es que desplaza un 1 un número de posiciones que establece la igualdad (numPins?—?1?—?i) --> 4-1-0 =3
la expresión 1 << 3 = 8 o en binario 00001000 J lo iguala y suma al resultado, J vale ahora 00001000

si la patilla 3 está a 0 no hará nada
si la patilla 4 esta a 1 entonces hará (numPins?—?1?—?i) --> 4-1-2 =1
la expresión 1 << 1 = 2 o en binario 00000010 J lo iguala y suma al resultado, j vale ahora 00001010
si la patilla 5 esta a 1 entonces hará (numPins?—?1?—?i) --> 4-1-3 =0
la expresión 1 << 0 = 1 o en binario 00000001 J lo iguala y suma al resultado, j vale ahora 00001011

acaba entonces la función y retorna j con el valor que ha calculado.

Creo que el problema está en la jerarquía de operadores, yo pondría j += (1«(numPins?—?1?—?i));

al meterlo entre paréntesis queda claro como se quiere hacer las operaciones en primer lugar.

ya nos cuentas si es esto lo que falla.

Hay que tener en cuenta el bit donde se guarda la información , yo lo habría hecho de otra forma, el bit LSB que se guarde siempre primero, de esa forma que lo hace la posición de la la primera lectura no siempre está en el mismo sitio, dependerá del número de patillas que se leen.
modificando la expresión se consigue esto que digo .

Un saludo

Como se nota que el que sabe sabe. iba a responderte pero en el tiempo de hacer la comprobacion aparecio DonGato y zan!!!

De todos modos yo revisaria esta linea

for(int i = 0; i <= 4; i++)

porque el array que tienes....
int DipPins[] = { 2, 3, 4, 5}

...es de 4 elementos entonces seria mejor
for(int i = 0; i < 4; i++) ó for(int i = 0; i <= 3; i++)

no se si eso produce un error o no, yo no soy un programador de los guenos y menos en C que es nuevo para mi.

Me da error en la linea en cuestión stray \ in programa, también de la forma que dices SrDongato. Zacarino lo del bucle esta mal, que cabeza la mia, que del 0 al 4 son 5 y la matriz es de 4.
Voy a seguir con ello, por cierto gracias a los dos no entendía como funciona el mover un bit.

Saludos.

Buenas Flico

He estado indagando en tu código, he corregido algunas cosas y creo saber por qué no funciona. ( o eso creo) no lo se a ciencia cierta.

(CREO) que la asignación de la variable no se puede hacer sobre la misma que se está haciendo el bitshift

( por favor que alguien lo corrobore)

te queda el código así, la función debe ir antes de ser llamado.

int DipPins[] = {  2, 3, 4, 5}; //DIP Switch Pins


//Read binary from DIP switches
byte readDIP(int* dipPins, int numPins)
{
  byte j = 0;
  byte a = 0;
  //byte j;
  //Get the switches state
  for(int i = 0; i < numPins; i++)
  {
    if (digitalRead(dipPins[i]))
    {
      j== j+1; // suma 1 solo si el pin está a 1
    }
    
      if (i<(numPins-1)) // mueve todos los bits menos el ultimo 
       {
       a == (j << 0); // mueve los bits, si j vale 1 movera un 0 si j vale 1 movera el 1 a la segunda posicion
       j == a;  // mueve a J lo calculado
       }
  }
  return j; //Return result
}

void setup()
{
  Serial.begin(9600);
  for(int i = 0; i <= 4; i++)
  {
    pinMode(DipPins[i], INPUT);       
   
  }
  delay(100);
}

void loop()
{
  byte DIPValue = readDIP(DipPins, 4);
  Serial.println(DIPValue, BIN);
  delay(1000);
}

Bueno, ya me cuentas :slight_smile: lo he compilado pero no lo he probado, ya nos cuentas. saludos ¡

Lo he probado y siempre da cero. Voy a probar a ir tocando el codigo ahora que lo has comentado y puedo seguir linea por linea.

Saludos.

Anoche a las 4 de la mañana estaba con la cabeza un poco espesa :smiley:

ya lo tienes aquí funcionando, me equivoqué al hacer las igualdades y otro par de cosas.

no utilizo el bitshift, solo multiplico por 2 que al caso es lo mismo.

te lo he probado y va Ok

int DipPins[] = {  2, 3, 4, 5}; //DIP Switch Pins


//Read binary from DIP switches
byte readDIP(int* dipPins, int numPins)
{
  byte j = 0;
  //byte j;
  //Get the switches state
  for(int i = 0; i < numPins; i++)
  {
    if (digitalRead(dipPins[i]))
    {
      j++; // suma 1 solo si el pin está a 1
    }
    
      if (i<(numPins-1)) // mueve todos los bits menos el ultimo 
       {
       j = j*2; // desplaza los bits 1 posicion a la izquierda
       }
  }
  return j; //Return result
}

void setup()
{
  Serial.begin(9600);
  for(int i = 0; i <= 4; i++)
  {
    pinMode(DipPins[i], INPUT);       
   
  }
  delay(100);
}

void loop()
{
  byte DIPValue = readDIP(DipPins, 4);
  Serial.println(DIPValue, BIN);
  delay(1000);
}

Yo no di con ello SrDonGato, estoy leyendo la ayuda para mover bits y voy probando a nivel superbasico, creo que asi dare con ello.
Para mi C me mata.
Si por ejemplo tengo esta variable byte valor = B01000000; y quiero leer el segundo bit empezando por la izquierda para meterlo en otra variable llamada digito, se haría también con bitshift?

Saludos y gracias por la ayuda.

el código que te he puesto antes funciona como querías.

otra forma de mover bits es multiplicando o dividiendo por potencias de 2.

si multiplicas por 2 haces que los bits se desplacen a la izquierda, si por el contrario divides entre 2 haces que se desplacen a la derecha.

hay alguna direfencia el hacer esto con el bitshift que como te digo

si tu byte valor = B01000000, lo divides entre 64 B00000001, este resultado lo haces un AND con B00000001 y lo metes en una variable.

si lo que quieres es saber si uno de los bits esta a 0 o 1 no hace falta que desplaces los bits, haces un

if ( valor && 64 ) variable = 1 else variable =0

un saludo

No, no era lo que te quería decir. Esta vez byte valor es (B10010010), quiero saber el valor de todos los bits para luego ir seleccionando con un

if digito1 {
variable1=1;
}
else {
variable1=0;
}

if digito2 {
variable2=1;
}
else {
variable2=0;
}

Seria como usar la funcion Mid de visualbasic.

Saludos.

creo que esto te valdrá

http://arduino.cc/en/Reference/BitRead

Cierto, tambien te valdrá eso.

basicamente es lo que tambien te digo yo,

si haces un AND con 1, estas evaluando el bit 1
si haces un AND con 2, estas evaluando el bit 2
si haces un AND con 4, estas evaluando el bit 3
si haces un AND con 8, estas evaluando el bit 4
si haces un AND con 16, estas evaluando el bit 5
y asi sucesivamente.

la ventaja de hacer ands es que puedes evaluar a la vez mas de 1 bit, por ejemplo si haces un and con 24, estas haciendo la evaluacion de los bits 4 y 5 a la vez ( que esten los dos a 1)

un saludo

Te cuento, cuando valor tiene algun bit a 1 la variable siempre es 1 aunque pongas en el and 1,2,4,8 ... valor&&

byte valor (B00100000);
int variable = 0;
void setup()
{
  Serial.begin(9600);
  
  if (valor && 2) {
    variable=1;
  } 
  else {
    variable=0; 
  }
  
  Serial.print(variable);
}

void loop()
{
 
}

Voy a probar mientras veo el futbol a mirarme un poco la función que dice aero_yo

Saludos.

Bueno aero_yo, he probado la función bitRead y he pillado como funciona.

byte valor (B00010010);
void setup()
{
  Serial.begin(9600);
  Serial.print(bitRead(valor,7));
  Serial.print(bitRead(valor,6));
  Serial.print(bitRead(valor,5));
  Serial.print(bitRead(valor,4));
  Serial.print(bitRead(valor,3));
  Serial.print(bitRead(valor,2));
  Serial.print(bitRead(valor,1));
  Serial.println(bitRead(valor,0));
  
}

void loop()
{
 
}

es la tipica función que cuando lees en la referencia no haces mucho caso, pero es muy útil!!

si quieres profundizar o saber más acerca de como hacerlo más "C", te dejo un tutorial muy bueno (en inglés)

http://www.avrfreaks.net/index.php?name=pnphpbb2&file=viewtopic&t=37871

el error está aqui

byte valor (B00100000);
int variable = 0;
void setup()
{
  Serial.begin(9600);
  
  if (valor & 2) {
    variable=1;
  } 
  else {
    variable=0; 
  }
  
  Serial.print(variable);
}

void loop()
{
 
}

es sólo un &, es da 1 si alguno de los bits esta a 1, si solo pones potencias de 2 miras un solo bit , si miras varios a la vez con que uno de los bits esté a 1 el IF será válido.

un saludo

La prueba que hice ayer con bitRead

byte valor (B00010010);
int variable = 0;
void setup()
{
  Serial.begin(9600);
  
  Serial.print(bitRead(valor,7));
  Serial.print(bitRead(valor,6));
  Serial.print(bitRead(valor,5));
  Serial.print(bitRead(valor,4));
  Serial.print(bitRead(valor,3));
  Serial.print(bitRead(valor,2));
  Serial.print(bitRead(valor,1));
  Serial.println(bitRead(valor,0));
  
}

void loop()
{
 
}

Saludos.

@SrDongato, he probado con & y también funciona. Siempre leía la referencia de arduino en español y resulta que hay muchos operadores que solamente están en la versión en ingles. Que cosas.
Lo que si me he dado cuenta es que cuando estudie electrónica en el instituto no di casi nada de digital y me pierdo en conceptos básicos. El que me daba tecnología se emociono el hombre con la teoría de los diodos.

Saludos