Go Down

Topic: Interrupt from i2c keypad (Read 132 times) previous topic - next topic

Marudher

Hey there,
We're beginners at arduino, but previously we had some fun with 80515 devices and assembly programming.
We're creating program for student's project that is replacing d'n'd cubes using:
keypad, i2c, arduino one r3 and multiplexed two digit sevseg displayers.
We already have used libraries<SevSeg.h><Keypad.h><Wire.h><Keypad_I2C.h>
So we noticed a problem that using in regular loop function getkey and refreshdisplay the display of numers on sevseg is delayed for about 20ms so it's blinking.
The problem is in awaiting for recive from the keypad in the loop, so we tried to make interrupt by:
-connecting int form i2c do int0
-use attachinterrupt(0, /a function/, change) in setup
-a function should be getting info of sda as char like this key = kpd.getKey() and then jump back to the loop

but it seems to not getting an interrupt from int0. Any button push on keypad is not changing anything.

Can you tell us in what theres would be a problem?
And if its about flag of interrupt how to define and control it (in assembler things seems more easy)?

We're attaching source code below.


Thanks in advance.

Koepel

#1
Jan 21, 2018, 06:20 pm Last Edit: Jan 21, 2018, 06:23 pm by Koepel
No one has answered yet, because it is a specific question and there is not enough information.

Can you give links to the used libraries ?
Can you show a schematic of your project ?

The "kpd.getKey()" function seems to use I2C, that is not good in a interrupt routine.

The Wire library uses also interrupts. In a interrupt routine, the interrupts are turned off. That will not work. The I2C takes some time. Try to keep the interrupt routine as short as possible.

I don't understand the data path with the 'key' variable. Once it is set to a value, the sketch never stops using it and the sevseg.setNumber() is called over and over again.

You could create a global boolean volatile variable and use that to tell that a key has been pressed.

Code: [Select]

volatile boolean newKeyInterrupt = false;

void loop() {
  if( newKeyInterrupt)
  {
    newKeyInterrupt = false;

    key = kpd.getKey();
    wybor = ...
    wyswietl = ...
 
    sevseg.setNumber(wyswietl, 2);
  }

  sevseg.refreshDisplay();        //przelaczenie wyswietlanej cyfey
}

void onStep() {
  newKeyInterrupt = true;
}


You could avoid all these problems with a keypad without I2C and with a OLED or Nextion or LCD display or a driver for the seven segment display.

Marudher

Thank you for the reply.

The thing is that when a specific button on keyboard is pressed it gives diffrent range for the random function f.e. button "1" gives a range between 1-4, button "2" between  1-5 and so on. So i would like to ask if function getkey will still return a variable form keyboard?

The links to libraries are here:
https://github.com/DeanIsMe/SevSeg
https://github.com/joeyoung/arduino_keypads/tree/master/Keypad_I2C
https://github.com/Chris--A/Keypad

The schematic is a little chaotic:
http://uploads.im/muk9Z.png

Thanks in advance.

Koepel

Schematic: you could use a GND symbol and a "bus" for the 'a'...'g' pins. Place the transistors under the displays and don't try to make it fit on a piece of paper.

The Keypad_I2C does not come with an example with an interrupt  :(

You use attachInterrupt() with CHANGE, I think it should be FALLING.
Is that interrupt always fired ? or should it be turned on ?

The SevSeg and Keypad libraries are also in the Library Manager in the IDE (but not the Keypad_I2C). When you use the Library Manager, it keeps track of updates.

I do not understand what you mean.
If a key is pressed, do you want to show a number ? Or do you want to change that number as long as the key is pressed and keep the last random number when the key is released ?

Marudher

The interrupt should occur when any button on keyboard is pressed also if a it's is pressed i want to show a random number depending on a specific range to that button.   

Go Up