[risolto]perplessità con sensore induttivo

ciao
per una applicazione che sto sviluppando, mi sono imbattuto in uno strano comportamento di un sensore induttivo (cinese), quello che accade è che quando muovo un oggetto metallico davanti al sensore lentamente ho una doppia eccitazione della elettrovalvola collegata attraverso degli shift register, mentre se lo muovo più velocemente questo non accade, c'è una spiegazione?

Grazie
Stefano

//versione con utilizzo dell'interrupts versione 2
/*
versione del 24092014
 stato: exe
 */

//codice sviluppato partendo dal lavoro dei sottoelencati autori
//  Author  : Carlyn Maw, Tom Igoe                                    
//  Notes   : Code for using a CD4021B Shift Register
//  Notes   : Code for using a 74hc595 Shift Register 	

/*il seguente codice utilizza le funzioni shifout
 e le funzioni shiftin, viene eseguito il controllo dello stato
 dei contatti su shiftin e la memorizzazione 
 nei registri di shiftin e riprodotti sui led dalla funzione shiftout
 il led sarà in parallelo alla elettrovalvola
 */

//pin per shiftout
byte dataPinOUT = 11; //Pin connected to DS of 74HC595 14
byte latchPinOUT = 8;//Pin connected to ST_CP of 74HC595 12
byte clockPinOUT = 12;//Pin connected to SH_CP of 74HC595 11

//pin per shiftin
byte dataPinIN = 7;//Pin connected to Q8 of 4021 3 
byte latchPinIN = 6;//Pin connected to P/SC of 4021 9
byte clockPinIN = 5;//Pin connected to CLOCK of 4021 10

//Define variables to hold the data 
//for shift register.
//starting with a non-zero numbers can help troubleshoot
byte switchVar1 = 78;  //01001110
byte switchVar2 = 159; //100111113

byte Var1,Var2;

int n, p;//contatori
int tempo0;
int ritardo[11] = {
  0, 20, 30, 45, 60, 60, 45, 30, 20, 0, 150};
int statosensore1;
byte pin_out = 4; //pin da collegare al pin_in della scheda della pinza shiftout

void setup() 
{
  //set pins to output so you can control the shift registers
  //shiftout define pin modes
  pinMode(dataPinOUT, OUTPUT);
  pinMode(latchPinOUT, OUTPUT);
  pinMode(clockPinOUT, OUTPUT);
  digitalWrite(latchPinOUT, LOW);

  //shiftin define pin modes
  pinMode(dataPinIN, INPUT);
  pinMode(latchPinIN, OUTPUT);
  pinMode(clockPinIN, OUTPUT); 


  pinMode(2, INPUT_PULLUP);
  attachInterrupt(0, sensore1, FALLING); //sensore induttivo collegato al pin 2

  pinMode(pin_out, OUTPUT);
  digitalWrite(pin_out, HIGH);

  statosensore1 = 0;  //stato iniziale del sensore

  Var1 = B00000000;
  Var2 = B00000000;

  //sezione per shiftout spegne tutti i led
  //delay(20);
  digitalWrite(latchPinOUT, LOW);                         //Pull latch LOW to start sending data
  shiftOut(dataPinOUT, clockPinOUT, MSBFIRST, Var2); //Send the data byte 2
  shiftOut(dataPinOUT, clockPinOUT, MSBFIRST, Var1); //Send the data byte 1
  digitalWrite(latchPinOUT, HIGH);                        //Pull latch HIGH to stop sending data
  //delay(10);

  Serial.begin(115200);
}

void loop() 
{
  //lettura dello stato dei pin in input
  //shiftin
  //Pulse the latch pin:

  digitalWrite(latchPinIN, 1);  //set it to 1 to collect parallel data, wait
  //delayMicroseconds(50);     
  digitalWrite(latchPinIN, 0); //set it to 0 to transmit data serially  
  //while the shift register is in serial mode
  //collect each shift register into a byte
  //the register attached to the chip comes in first 
  switchVar1 = shiftIn(dataPinIN, clockPinIN);
  switchVar2 = shiftIn(dataPinIN, clockPinIN);
  /*
  Serial.print(switchVar1, BIN);
   Serial.print('\t');
   Serial.println(switchVar2, BIN);
   */
  /*  //sezione per shiftout spegne tutti i led
   Var1 = B00000000;
   Var2 = B00000000;
   //delay(20);
   digitalWrite(latchPinOUT, LOW);                         //Pull latch LOW to start sending data
   shiftOut(dataPinOUT, clockPinOUT, MSBFIRST, Var2); //Send the data byte 2
   shiftOut(dataPinOUT, clockPinOUT, MSBFIRST, Var1); //Send the data byte 1
   digitalWrite(latchPinOUT, HIGH);                        //Pull latch HIGH to stop sending data
   //delay(10);
   */

  //questa sezione è il cuore e scopo del programma
  //lo shiftin ha memorizzato lo stato dei 10 sensori HIGH o LOW
  //per la verifica della presenza o meno della pianta nel condotto

  n = 0;
  //p=0;

  if(switchVar1 == B00000000 && switchVar2 == B00000000)//per caricare il distributore al primo giro
  {
    digitalWrite(pin_out, LOW);
    delay(500);
    digitalWrite(pin_out, HIGH);
  }

  //primo ciclo do per le prime 5 posizioni 1-5
  do
  {
    if(statosensore1 == 1)
    {
      do
      {
        if (bitRead(switchVar1,n) == LOW) //verifica il valore del bit nella variabile 1
          //LOW pianta presente HIGH pianta assente
        {
          delay(ritardo[n]);      //ritardo tra una fila e l'altra

          bitWrite(Var1, n, HIGH);//scrive nella varialbile per eccittare l'elettrovalvola

          digitalWrite(latchPinOUT, LOW);                       //Pull latch LOW to start sending data
          shiftOut(dataPinOUT, clockPinOUT, MSBFIRST, Var2);  //Send the data byte 2
          shiftOut(dataPinOUT, clockPinOUT, MSBFIRST, Var1);    //Send the data byte 1 eccita l'elettrovalvola
          digitalWrite(latchPinOUT, HIGH);                      //Pull latch HIGH to stop sending data

          delay(ritardo[10]);  //ritardo per lo scarico della pianta

          bitWrite(Var1, n, LOW);//scrive nella varialbile per diseccittare l'elettrovalvola

          digitalWrite(latchPinOUT, LOW);                     //Pull latch LOW to start sending data
          shiftOut(dataPinOUT, clockPinOUT, MSBFIRST, Var2);  //Send the data byte 2
          shiftOut(dataPinOUT, clockPinOUT, MSBFIRST, Var1);  //Send the data byte 1
          digitalWrite(latchPinOUT, HIGH);                    //Pull latch HIGH to stop sending data
          statosensore1 = 0;
        }
        n++;
      }
      while(statosensore1 == 1 && n < 5);
    } 
  }
  while(n < 5);

  //inizio secondo ciclo do 6-10
  do
  {
    if (statosensore1 == 1)
    {
      do
      {
        if (bitRead(switchVar2, n-5) == LOW) //verifica il valore del bit nella variabile 1
        {
          delay(ritardo[n]);  //ritardo tra una fila e l'altra

          bitWrite(Var2,n-5,HIGH);//eccita l'elettrovalvola

          digitalWrite(latchPinOUT, LOW);                       //Pull latch LOW to start sending data
          shiftOut(dataPinOUT, clockPinOUT, MSBFIRST, Var2);  //Send the data byte 2
          shiftOut(dataPinOUT, clockPinOUT, MSBFIRST, Var1);    //Send the data byte 1
          digitalWrite(latchPinOUT, HIGH);                      //Pull latch HIGH to stop sending data

          delay(ritardo[10]);  //ritardo per lo scarico della pianta

          bitWrite(Var2,n-5,LOW);//diseccita l'elettrovalvola

          digitalWrite(latchPinOUT, LOW);                    //Pull latch LOW to start sending data
          shiftOut(dataPinOUT, clockPinOUT, MSBFIRST, Var2); //Send the data byte 2
          shiftOut(dataPinOUT, clockPinOUT, MSBFIRST, Var1); //Send the data byte 1
          digitalWrite(latchPinOUT, HIGH);                   //Pull latch HIGH to stop sending data

          statosensore1 = 0;
          // p++;
          //Serial.println(n);
          //Serial.println(ritardo+(9-n)*deltaR);
        }
        n++;
      }
      while(statosensore1 == 1 && n < 10);
      //p=0;
    }    nc
  }
  while (n < 10);
}//fine loop



void sensore1() //pin 2 a cui attaccare il sensore induttivo
{
  statosensore1 = 1;
}

//shiftIn function

///// just needs the location of the data pin and the clock pin
///// it returns a byte with each bit in the byte corresponding
///// to a pin on the shift register. leftBit 7 = Pin 7 / Bit 0= Pin 0

byte shiftIn(int myDataPin, int myClockPin)
{
  int i;
  int temp = 0;
  int pinState;
  byte myDataIn = 0;

  pinMode(myClockPin, OUTPUT);
  pinMode(myDataPin, INPUT);
  //we will be holding the clock pin high 8 times (0,..,7) at the
  //end of each time through the for loop

  //at the begining of each loop when we set the clock low, it will
  //be doing the necessary low to high drop to cause the shift
  //register's DataPin to change state based on the value
  //of the next bit in its serial information flow.
  //The register transmits the information about the pins from pin 7 to pin 0
  //so that is why our function counts down
  for (i=7; i>=0; i--)
  {
    digitalWrite(myClockPin, 0);
    delayMicroseconds(2);
    temp = digitalRead(myDataPin);
    if (temp) {
      pinState = 1;
      //set the bit to 0 no matter what
      myDataIn = myDataIn | (1 << i);
    }
    else {
      //turn it off -- only necessary for debuging
      //print statement since myDataIn starts as 0
      pinState = 0;
    }

    //Debuging print statements
    //Serial.print(pinState);
    //Serial.print("     ");
    //Serial.println (dataIn, BIN);

    digitalWrite(myClockPin, 1);

  }
  //debuging print statements whitespace
  //Serial.println();
  //Serial.println(myDataIn, BIN);
  return myDataIn;
}

c'è una spiegazione?

sí; mi serve una sfera di crisallo. :wink: :wink: :wink: :wink: :wink:
Che sensore hai comprato???????????
Modello, sito del venditore, datasheeet ecc.
Ciao Uwe

ciao
il sensore è cinese quello che ho trovato è questo:

Product Name : Proximity Switch;
Model : LJ12A3-4-Z/BX;
Type : DC 3 Wire Type (Brown, Blue. Black);
Switch Appearance Type : Cylinder Type
Theory : Induction Sensor;
Output Type : NPN NO(Normal Open);
Diameter of Head : 10.5mm/ 0.42"
Detecting Distance : 4mm/ 0.16";
Work Voltage : DC 6-36V;
Consumption Corrent : Max 200mA

il fotoaccoppiatore è un 4N32, ho provato un diverso collegamento ma con lo stesso risultato.
Ho verificato anche con un oscilloscopio ma non ho fronti di salita/discesa impropri.
Ho fatto anche un sensore uguale a tavolino ma con questo nuovo schema ma non si verifica questo comportamento
Ho replicato a tavolino lo schema ma non si verifica questo comportamento.

stefano

o il sensore non e' quello di cui alleghi i dati o lo schema ( che prima avevi linkato ) e' errato

ciao
il cinese mi da questo schema:
http://www.ebay.it/itm/5pcs-Inductive-Proximity-Sensor-Detection-Switch-NPN-DC6-36V-LJ12A3-4-Z-BX-/290669106985?pt=LH_DefaultDomain_0&hash=item43ad3a9729
allegato lo schema che ho provato stamatina e che funziona meglio cambiando nello sketch FALLING con RISING, e mettendo volatile la variabile dell'interrupt (me lo ero dimenticato), dico meglio perchè talvolta ho ancora un doppio segnale durante il passaggio di un solo dente dente davanti al sensore, la frequenza è di 1 dente/2 secondi e talvolta qualche dente viene visto dal sensore ma non dalla scheda, ho replicato lo schema allegato a tavolino con uno sketch per contare gli impulsi,ma non ho questo problema.

Stefano

t_completo.pdf (5.5 KB)

esatto

ciao
con lo schema è esatto dove potrebbe essere il problema? il led del sensore segnala sempre un passaggio.Ho provato anche un sensore di marca ma ho sempre lo stesso problema.

Se guardi lo sketch del pimo Tuo post ha troppi delay e puó perdere la segnalazione di un impulso pervenuto dal sensore.
Togli tutti i delay.

Ciao Uwe

ciao
grazie per il suggerimento, stavo appunto riflettendo sulla influenza dei delay(), provo a riscrivere usando il millis()

Stefano

Ho eliminato i delay(), la situazione è migliorata ma ci sono ancora dei doppi impulsi.
Credo che possa trattarsi di un problema hardware, perchè gli stessi collegamenti a tavolino non danno problemi.
Domani provo a pulire le piste a verniciarle e verifico ancora i collegamenti.

Stefano

Rimandaci lo sketch modificato.
Ciao Uwe

ho dovuto lasciare un delay altrimenti l'ultima elettrovalvola della serie non si eccitava, ho messo un Serial.print() e da quello che scrive con un solo impulso, a volte una parte dello sketch viene eseguito più volte come se ci fosse più di un impulso, inoltre questo comportamento non essendo regolare mi fa pensare che possa esserci un problema di collegamenti

questo è l'ultima versione dello sketch:

//versione con utilizzo dell'interrupts versione 2
/*
versione del 24092014
 stato: exe
 */

//codice sviluppato partendo dal lavoro dei sottoelencati autori
//  Author  : Carlyn Maw, Tom Igoe                                    
//  Notes   : Code for using a CD4021B Shift Register
//  Notes   : Code for using a 74hc595 Shift Register 	

/*il seguente codice utilizza le funzioni shifout
 e le funzioni shiftin, viene eseguito il controllo dello stato
 dei contatti su shiftin e la memorizzazione 
 nei registri di shiftin e riprodotti sui led dalla funzione shiftout
 il led sarà in parallelo alla elettrovalvola
 */

//pin per shiftout
byte dataPinOUT = 11; //Pin connected to DS of 74HC595 14
byte latchPinOUT = 8;//Pin connected to ST_CP of 74HC595 12
byte clockPinOUT = 12;//Pin connected to SH_CP of 74HC595 11

//pin per shiftin
byte dataPinIN = 7;//Pin connected to Q8 of 4021 3 
byte latchPinIN = 6;//Pin connected to P/SC of 4021 9
byte clockPinIN = 5;//Pin connected to CLOCK of 4021 10

//Define variables to hold the data 
//for shift register.
//starting with a non-zero numbers can help troubleshoot
byte switchVar1;  //01001110
byte switchVar2; //100111113

byte Var1,Var2;

int n, i;//contatore
int ritardo[11] = {
  0, 20, 30, 45, 60, 60, 45, 30, 20, 0, 150};

volatile byte statosensore1;

byte pin_out = 4; //pin da collegare al pin_in della scheda della pinza shiftout

void setup() 
{
  //set pins to output so you can control the shift registers
  //shiftout define pin modes
  pinMode(dataPinOUT, OUTPUT);
  pinMode(latchPinOUT, OUTPUT);
  pinMode(clockPinOUT, OUTPUT);
  digitalWrite(latchPinOUT, LOW);

  //shiftin define pin modes
  pinMode(dataPinIN, INPUT);
  pinMode(latchPinIN, OUTPUT);
  pinMode(clockPinIN, OUTPUT); 

  pinMode(2, INPUT_PULLUP);
  attachInterrupt(0, sensore1, RISING); //sensore induttivo collegato al pin 2

  pinMode(pin_out, OUTPUT);
  digitalWrite(pin_out, HIGH);

  statosensore1 = 0;  //stato iniziale del sensore

  Var1 = B00000000;
  Var2 = B00000000;

  switchVar1 = B00000000;
  switchVar2 = B00000000;

  //sezione per shiftout spegne tutti i led
  delay(20);
  digitalWrite(latchPinOUT, LOW);                         //Pull latch LOW to start sending data
  shiftOut(dataPinOUT, clockPinOUT, MSBFIRST, Var2); //Send the data byte 2
  shiftOut(dataPinOUT, clockPinOUT, MSBFIRST, Var1); //Send the data byte 1
  delayMicroseconds(50);
  digitalWrite(latchPinOUT, HIGH);                        //Pull latch HIGH to stop sending data

i = 0;

  Serial.begin(115200);
}

void loop() 
{
  //lettura dello stato dei pin in input
  //shiftin
  //Pulse the latch pin:

  digitalWrite(latchPinIN, HIGH);  //set it to 1 to collect parallel data, wait
  delayMicroseconds(50);     
  digitalWrite(latchPinIN, LOW); //set it to 0 to transmit data serially  
  //while the shift register is in serial mode
  //collect each shift register into a byte
  //the register attached to the chip comes in first 
  switchVar1 = shiftIn(dataPinIN, clockPinIN);
  switchVar2 = shiftIn(dataPinIN, clockPinIN);
  /*
  Serial.print(switchVar1, BIN);
   Serial.print('\t');
   Serial.p'9intln(switchVar2, BIN);
   */
  //questa sezione è il cuore e scopo del programma
  //lo shiftin ha memorizzato lo stato dei 10 sensori HIGH o LOW
  //per la verifica della presenza o meno della pianta nel condotto

  n = 0;

  if(switchVar1 == B00000000 && switchVar2 == B00000000)//per caricare il distributore al primo giro
  {
    digitalWrite(pin_out, LOW);
    delay(500);
    digitalWrite(pin_out, HIGH);
  }

  /* Serial.print(switchVar1,BIN);
   Serial.println('\t');
   Serial.println(switchVar2,BIN);
   */
  //primo ciclo do per le prime 5 posizioni 1-5
  do
  {
    if (statosensore1 == 1)
    {
      Serial.println(i++);
      do
      {
        if (bitRead(switchVar1, n) == 0) //H assente L presente
        {
          // delay(ritardo[n]);//ritardo tra una fila e l'altra

          bitWrite(Var1, n, 1);// 1 EV on

          digitalWrite(latchPinOUT, LOW);                       //Pull latch LOW to start sending data
          shiftOut(dataPinOUT, clockPinOUT, MSBFIRST, Var2);  //Send the data byte 2
          shiftOut(dataPinOUT, clockPinOUT, MSBFIRST, Var1);    //Send the data byte 1
          digitalWrite(latchPinOUT, HIGH);                      //Pull latch HIGH to stop sending data

          statosensore1 = 0;
        }
        n++;
      }
      while(statosensore1 == 1 && n < 5);
    }
  }
  while(n < 5);
  
    // EV off
    delay(ritardo[10]);
    Var2 = B00000000;
    Var1 = B00000000;          
    digitalWrite(latchPinOUT, LOW);                     //Pull latch LOW to start sending data
    shiftOut(dataPinOUT, clockPinOUT, MSBFIRST, Var2);  //Send the data byte 2
    shiftOut(dataPinOUT, clockPinOUT, MSBFIRST, Var1);    //Send the data byte 1
    digitalWrite(latchPinOUT, HIGH);                    //Pull latch HIGH to stop sending data 

  //inizio secondo ciclo do 6-10
  do
  {
    if (statosensore1 == 1)
    {
      Serial.println(i++);
      do
      {
        if (bitRead(switchVar2, n-5) == 0) // H assente L presente
        {
          //delay(ritardo[n]);//ritardo tra una fila e l'altra

          bitWrite(Var2, n-5, 1);// 1 EV on

          digitalWrite(latchPinOUT, LOW);                       //Pull latch LOW to start sending data
          shiftOut(dataPinOUT, clockPinOUT, MSBFIRST, Var2);  //Send the data byte 2
          shiftOut(dataPinOUT, clockPinOUT, MSBFIRST, Var1);    //Send the data byte 1
          digitalWrite(latchPinOUT, HIGH);                      //Pull latch HIGH to stop sending data
          
          statosensore1 = 0;
        }
        n++;
      }
      while(statosensore1 == 1 && n < 10);
    }

  }
  while (n < 10);
  
    // EV off
    delay(ritardo[10]);
    Var2 = B00000000;
    Var1 = B00000000;          
    digitalWrite(latchPinOUT, LOW);                     //Pull latch LOW to start sending data
    shiftOut(dataPinOUT, clockPinOUT, MSBFIRST, Var2);  //Send the data byte 2
    shiftOut(dataPinOUT, clockPinOUT, MSBFIRST, Var1);    //Send the data byte 1
    digitalWrite(latchPinOUT, HIGH);                    //Pull latch HIGH to stop sending data
}//fine loop



void sensore1() //attaccato al pin 2 a cui attaccare il sensore induttivo
{
  statosensore1 = 1;
}

//shiftIn function

///// just needs the location of the data pin and the clock pin
///// it returns a byte with each bit in the byte corresponding
///// to a pin on the shift register. leftBit 7 = Pin 7 / Bit 0= Pin 0

byte shiftIn(int myDataPin, int myClockPin)
{
  int i;
  int temp = 0;
  int pinState;
  byte myDataIn = 0;

  pinMode(myClockPin, OUTPUT);
  pinMode(myDataPin, INPUT);
  //we will be holding the clock pin high 8 times (0,..,7) at the
  //end of each time through the for loop

  //at the begining of each loop when we set the clock low, it will
  //be doing the necessary low to high drop to cause the shift
  //register's DataPin to change state based on the value
  //of the next bit in its serial information flow.
  //The register transmits the information about the pins from pin 7 to pin 0
  //so that is why our function counts down
  for (i=7; i>=0; i--)
  {
    digitalWrite(myClockPin, 0);
    delayMicroseconds(2);
    temp = digitalRead(myDataPin);
    if (temp) {
      pinState = 1;
      //set the bit to 0 no matter what
      myDataIn = myDataIn | (1 << i);
    }
    else {
      //turn it off -- only necessary for debuging
      //print statement since myDataIn starts as 0
      pinState = 0;
    }

    //Debuging print statements
    //Serial.print(pinState);
    //Serial.print("     ");
    //Serial.println (dataIn, BIN);

    digitalWrite(myClockPin, 1);

  }
  //debuging print statements whitespace
  //Serial.println();
  //Serial.println(myDataIn, BIN);
  return myDataIn;
}

ciao
facendo delle prove con uno sketch ridotto, ho scoperto che la parte di codice dentro IF viene eseguito, in altre parole sembra che l'interrupt venga invocato senza che il sensore sia utilizzato

//pin per shiftout
byte dataPinOUT = 11; //Pin connected to DS of 74HC595 14
byte latchPinOUT = 8;//Pin connected to ST_CP of 74HC595 12
byte clockPinOUT = 12;//Pin connected to SH_CP of 74HC595 11

//pin per shiftin
byte dataPinIN = 7;//Pin connected to Q8 of 4021 3 
byte latchPinIN = 6;//Pin connected to P/SC of 4021 9
byte clockPinIN = 5;//Pin connected to CLOCK of 4021 10

//Define variables to hold the data 
//for shift register.
//starting with a non-zero numbers can help troubleshoot
byte switchVar1;
byte switchVar2;

byte Var1, Var2;

int n;//contatore
int ritardo[11] = {
  0, 20, 30, 45, 60, 60, 45, 30, 20, 0, 150};

volatile byte statosensore1;

byte pin_out = 4; //pin da collegare al pin_in della scheda della pinza shiftout

void setup() 
{
  //set pins to output so you can control the shift registers
  //shiftout define pin modes
  pinMode(dataPinOUT, OUTPUT);
  pinMode(latchPinOUT, OUTPUT);
  pinMode(clockPinOUT, OUTPUT);
  digitalWrite(latchPinOUT, LOW);

  //shiftin define pin modes
  pinMode(dataPinIN, INPUT);
  pinMode(latchPinIN, OUTPUT);
  pinMode(clockPinIN, OUTPUT); 

  pinMode(2, INPUT_PULLUP);
  attachInterrupt(0, sensore1, RISING); //sensore induttivo collegato al pin 2

  pinMode(pin_out, OUTPUT);
  digitalWrite(pin_out, HIGH);

  statosensore1 = 0;  //stato iniziale del sensore

  Var1 = B00000000;
  Var2 = B00000000;

  switchVar1 = B00000000;
  switchVar2 = B00000000;

  //sezione per shiftout spegne tutti i led
  digitalWrite(latchPinOUT, LOW);                         //Pull latch LOW to start sending data
  shiftOut(dataPinOUT, clockPinOUT, MSBFIRST, Var2); //Send the data byte 2
  shiftOut(dataPinOUT, clockPinOUT, MSBFIRST, Var1); //Send the data byte 1
  delayMicroseconds(50);
  digitalWrite(latchPinOUT, HIGH);                        //Pull latch HIGH to stop sending data

  Serial.begin(115200);
}

void loop() 
{
  digitalWrite(latchPinIN, HIGH);  //set it to 1 to collect parallel data, wait
  delayMicroseconds(50);     
  digitalWrite(latchPinIN, LOW); //set it to 0 to transmit data serially  
  //while the shift register is in serial mode
  //collect each shift register into a byte
  //the register attached to the chip comes in first 
  switchVar1 = shiftIn(dataPinIN, clockPinIN);
  switchVar2 = shiftIn(dataPinIN, clockPinIN);
  /*
  Serial.print(switchVar1, BIN);
   Serial.print('\t');
   Serial.p'9intln(switchVar2, BIN);
   */
  Serial.print("statosensore1");
  Serial.print('\t');
  Serial.println(statosensore1);

  if(statosensore1 == 1 && n < 5);
  {
Serial.println(n);
    if (bitRead(switchVar1, n) == 0) //H assente L presente    {
      // delay(ritardo[n]);//ritardo tra una fila e l'altra
      
      bitWrite(Var1, n, 1);// 1 EV on

      digitalWrite(latchPinOUT, LOW);                       //Pull latch LOW to start sending data
      shiftOut(dataPinOUT, clockPinOUT, MSBFIRST, Var2);  //Send the data byte 2
      shiftOut(dataPinOUT, clockPinOUT, MSBFIRST, Var1);    //Send the data byte 1
      digitalWrite(latchPinOUT, HIGH);                      //Pull latch HIGH to stop sending data

      // EV off
      delay(ritardo[10]);
      Var2 = B00000000;
      Var1 = B00000000;          
      digitalWrite(latchPinOUT, LOW);                     //Pull latch LOW to start sending data
      shiftOut(dataPinOUT, clockPinOUT, MSBFIRST, Var2);  //Send the data byte 2
      shiftOut(dataPinOUT, clockPinOUT, MSBFIRST, Var1);    //Send the data byte 1
      digitalWrite(latchPinOUT, HIGH);                    //Pull latch HIGH to stop sending data 

      statosensore1 = 0;
    }
    n++;
  }

  if(n == 5)
  {
    n = 0;
  }
}//fine loop



void sensore1() //sul pin 2
{
  statosensore1 = 1;
}

//shiftIn function

///// just needs the location of the data pin and the clock pin
///// it returns a byte with each bit in the byte corresponding
///// to a pin on the shift register. leftBit 7 = Pin 7 / Bit 0= Pin 0

byte shiftIn(int myDataPin, int myClockPin)
{
  int i;
  int temp = 0;
  int pinState;
  byte myDataIn = 0;

  pinMode(myClockPin, OUTPUT);
  pinMode(myDataPin, INPUT);
  //we will be holding the clock pin high 8 times (0,..,7) at the
  //end of each time through the for loop

  //at the begining of each loop when we set the clock low, it will
  //be doing the necessary low to high drop to cause the shift
  //register's DataPin to change state based on the value
  //of the next bit in its serial information flow.
  //The register transmits the information about the pins from pin 7 to pin 0
  //so that is why our function counts down
  for (i=7; i>=0; i--)
  {
    digitalWrite(myClockPin, 0);
    delayMicroseconds(2);
    temp = digitalRead(myDataPin);
    if (temp) {
      pinState = 1;
      //set the bit to 0 no matter what
      myDataIn = myDataIn | (1 << i);
    }
    else {
      //turn it off -- only necessary for debuging
      //print statement since myDataIn starts as 0
      pinState = 0;
    }

    //Debuging print statements
    //Serial.print(pinState);
    //Serial.print("     ");
    //Serial.println (dataIn, BIN);

    digitalWrite(myClockPin, 1);

  }
  //debuging print statements whitespace
  //Serial.println();
  //Serial.println(myDataIn, BIN);
  return myDataIn;
}

questo è l'output

statosensore1	1
0
statosensore1	1
1
statosensore1	1
2
statosensore1	1
3
statosensore1	1
4
statosensore1	1

ciao
ho sostituito il sensore induttivo con un sensore fotoelettrico, adesso funziona ma spero di avere la stessa precisione anche con un poca polvere.

grazie
Stefano

stefa24:
in altre parole sembra che l'interrupt venga invocato senza che il sensore sia utilizzato

Non è possibile. Se non si verifica sul pin l'evento per cui hai settato l'interrupt, la relativa ISR non viene sollevata. Se l'interrupt viene sollevato significa che il micro ha visto un RISING sul pin. Però tu scartavi questo nei primi post. Ma che valori di tensione hai in ingresso al pin? Se la tensione quando il sensore non è attivato non è prossima a 0V può darsi che tu abbia delle fluttuazioni: se le fluttuazioni ricadono nel range di segnale indefinito del pin, il pn può leggere anche valori errati. Sull'Atmega tutto ciò che è compreso 0,3VCC e 0,6VCC (quindi tra 1,5V e 3,0V) può essere interpretato casualmente.

Infatti l'interrupt mi piace proprio per questo comportamento.
In ingresso al pin ho
0.6v sensore attivo suo led acceso
4.97 sensore disattivo suo led spento.
La mia perplessità nasce dal fatto che con l'oscilloscopio non vedevo nessun altro RISING, durante il tempo di sensore attivo e nessun RISING durante il tempo di sensore disattivo.
Per adesso ho risolto con il sensore fotoelettrico ma vorrei capire cosa succede con quello induttivo.

Scusa un attimo:

stefa24:
In ingresso al pin ho
0.6v sensore attivo suo led acceso
4.97 sensore disattivo suo led spento.
La mia perplessità nasce dal fatto che con l'oscilloscopio non vedevo nessun altro RISING, durante il tempo di sensore attivo e nessun RISING durante il tempo di sensore disattivo.

RISING fa scattare l'interrupt quando il segnale sul pin passa da LOW ad HIGH. Ma tu dici però che hai 0,6V con sensore attivo e 4,97V con sensore disattivo. Quindi RISING non va bene nel tuo caso. Tu hai la situazione opposta: hai un segnale HIGH che passa a LOW quando il sensore si attiva, per cui devi usare o FALLING (che scatta nel momento in cui il segnale cade) oppure LOW, che fa scattare l'interrupt quando il segnale ha raggiunto lo stato LOW.

Per l'applicazione è indifferente, a me interessa il momento, che sia RISING o FALLING non è fondamentale, oggi faccio altre prove e posto i risultati dell'output.

Grazie
Stefano

stefa24:
La mia perplessità nasce dal fatto che con l'oscilloscopio non vedevo nessun altro RISING, durante il tempo di sensore attivo e nessun RISING durante il tempo di sensore disattivo.

Il fatto che non lo vedi non significa che non ci sia, l'AVR vede impulsi maggiori di 62.5 nanosecondi, con l'oscilloscopio non li vedi a meno che non disponi di un ottimo DSO correttamente settato per catturarli.

Ho risolto mettendo una resistenza da 100k tra la base e emettitore pin 4 e 6 del fotoaccopiattore, come da schema.

Stefano

t_completo.pdf (5.65 KB)