Is there a way to check all inputs through 1 command on ind.IO and get the result in a byte ?

Hi,

I am trying to count pulses on 4 digital input pins with a frequency around 5Khz.

I try to do this through the interrupt generated by the expander.

After the interruptsignal is generated i need to read the imputs to check which input did generate the interrupt.

I can do this input by input but is slows down the process since every read action is a command to the expander chip. Is there a way read all inputs with 1 command and then store the result in a byte.

This byte can be used to compare with the previous input state byte to determine which input did generate the interrupt.

 

Regards,

Jeroen.

  

Jeroen Hollemans
Jeroen Hollemans
7
| 1 1 2
Asked on 1/18/17, 11:43 PM
0
vote
2744 Views

Stefano, Thanks for looking at it from a different view. counting every change /2 is less code and faster. I Will try this.

Jeroen Hollemans
on 1/22/17, 11:50 AM

Hi,

I did find a way (for 2 channels for now) but i am still limited to +/- 1 Khz.

Below the part of the code to check which ch did fire the interrupt.

If anyone has a suggestion on how to improve this to get to 5 Khz. (I2C is already pimped to 400Khz via twi.h file #define TWI_FREQ 400000L

Thanks,
Jeroen

void setup() {

  Serial.begin(9600);
  lcd.begin();
  Indio.digitalMode(1, INPUT); // Set CH1 as an input
  Indio.digitalMode(8, OUTPUT); // Set CH8 as an output

  attachInterrupt(7, setintflag, FALLING);       // INT7 attached to the interrupt of the expander, falling edge when portchange occurs
                                          
}

void setintflag() {
  interruptflag=1;
}

void loop() {
  if (interruptflag){
      Wire.requestFrom(33, 1);    // request 1 byte from slave device #33 eg. read first inputregister
      inputbyte0 = Wire.read(); // receive a byte
   
      if (inputbyte0 & 0b10000000 == 0b10000000) {   // check if ch1 is high through mask
          currch1in=1;
      }
      else {                                         // else ch1 is low
          currch1in=0;
      }
      if (prevch1in == 0 and currch1in == 1) {      //rising edge = increment counter and change prev state
          ch1counter++;
          prevch1in=1;
      }
      if (prevch1in == 1 and currch1in == 0) {      //falling edge = change prev state
          prevch1in=0;
      }
      if (inputbyte0 & 0b01000000 == 0b01000000) {   // check if ch2 is high through mask
          currch2in=1;
      }
      else {                                         // else ch2 is low
          currch2in=0;
      }
      if (prevch2in == 0 and currch2in == 1) {      //rising edge = increment counter and change prev state
          ch2counter++;
          prevch2in=1;
      }
      if (prevch2in == 1 and currch2in == 0) {      //falling edge = change prev state
          prevch2in=0;
      }
    interruptflag=0;
  }

Jeroen Hollemans
Jeroen Hollemans
7
| 1 1 2
Answered on 1/20/17, 10:23 PM
0
vote

First of all, did you check the timing of your Wire operations? Because if that's not fast enough, there's no trick to be added here. About your code, there are smarter ways to do things around. To fetch bits you can shift your byte left or right, so each time your bit falls directly in your variable. But you can also check them all in one go, by working directly on the entire byte in one go and then shifting the bits of the result. You can XOR the entire byte to know which bits have changed and then shift them in place, possibly in an array of counters, more or less like this: byte flag = prev ^ new; //XOR operation byte prev = new; //update prev for (byte xx=0; xx

Stefano Giuseppe Bonvini
on 1/21/17, 9:18 AM

Stefano, Problem with xor is that it matches both 0->1 and 1->0. So i stil neem to check for that. It seems to me that that part is fast enough since it happens at processor Clock speed but i will look intro it. In my first design i online had 1 input to check so i could use the interrupt to increment a timer. This worked well for 1 input with +/- 10khz squarewave in. With I2C on 400 kHz and +/- 50 bits for read and write i should be able to reach 8 kHz. At faster speeds the interrups will occure before the readcycle is finished.

Jeroen Hollemans
on 1/22/17, 12:13 AM

A change is a change, just count twice and then divide by two at display time.

We are looking for a smart solution here, right, not logical by the book.

 

 

Da: Jeroen Hollemans [mailto:jeroen2@industruino.com]
Inviato: 22 January 2017 01:13
A: Stefano Ariel Bonvini
Oggetto: Re: Is there a way to check all inputs through 1 command on ind.IO and get the result in a byte ? (299)

 

Stefano, Problem with xor is that it matches both 0->1 and 1->0. So i stil neem to check for that. It seems to me that that part is fast enough since it happens at processor Clock speed but i will look intro it. In my first design i online had 1 input to check so i could use the interrupt to increment a timer. This worked well for 1 input with +/- 10khz squarewave in. With I2C on 400 kHz and +/- 50 bits for read and write i should be able to reach 8 kHz. At faster speeds the interrups will occure before the readcycle is finished.

--
Jeroen Hollemans
Sent by Industruino using Odoo about Forum Post Is there a way to check all inputs through 1 command on ind.IO and get the result in a byte ? (299)

Stefano Giuseppe Bonvini
on 1/22/17, 7:10 AM

Hello,
yes there is.


I don't remember from the top of my head, but if you check the chip installed in Indio board, should start with PCA, you can then find its datasheet and there is a register that can be read through i2c to get this value.


Actually the library takes this values and check it against each byte, so you could also find reference to this register in the Indio.digitalRead function in Indio.h file, I guess.


Sorry for the unprecise answer, but I don't have a system available at the moment!

Stefano Giuseppe Bonvini
Stefano Giuseppe Bonvini
577
| 2 0 2
Answered on 1/20/17, 9:58 AM
0
vote

Your answer

Please try to give a substantial answer. If you wanted to comment on the question or answer, just use the commenting tool. Please remember that you can always revise your answers - no need to answer the same question twice. Also, please don't forget to vote - it really helps to select the best questions and answers!

Ask a Question

Keep Informed

About This Forum

This community is for professionals and enthusiasts of our products and services.

Read Guidelines

Question tools

32 follower(s)

Stats

Asked: 1/18/17, 11:43 PM
Seen: 2744 times
Last updated: 1/22/17, 11:50 AM