Closed linuxlurak closed 5 years ago
Not by me, sorry. I don't have the time to delve into this chip. Since I don't use it, I don't have a personal interest in it. I should mention that the chip is quite different from the ATmega series.
I will leave this open until May 2018 in case someone decides that they want to tackle it.
+1
@linuxlurak Do you need this library to work on esp8266 ? Maybe I can try to do something during this year! attachInterrupt(digitalPinToInterrupt(interruptPin), handleInterruptFunc, InterruptStateFR); I think that "attachInterrupt" works on esp8266, you should try it !
From ESP8266 core reference
Pin interrupts are supported through attachInterrupt, detachInterrupt functions. Interrupts may be attached to any GPIO pin, except GPIO16. Standard Arduino interrupt types are supported: CHANGE, RISING, FALLING.
http://esp8266.github.io/Arduino/versions/2.1.0-rc2/doc/reference.html
@zoomx Yes but we don't get a way to Determine the Pin That Was Interrupted. I needed that for a project and I had to fallback to a conventional port check every N ms.
@SamuelM333 Just create a interrupt handler for each pin that pass it's pin to your general interrupt handler.
void interruptHandler( uint8_t pin){
// do something base on pin
switch(pin){
case 1: //something important
break;
case 2: // something important for pin 2
break;
default :;
}
}
void pin1(void){
interruptHandler(1);
}
void pin2(void){
interruptHandler(2);
}
attachInterrupt(digitalPinToInterrupt(1),pin1,change);
attachInterrupt(digitalPinToInterrupt(2),pin2,change);
Chuck.
@stickbreaker I need to add the handlers in a dynamic way. I get some IoT task from a DB with the ports that I want to operate, so that's not an option for me. Thanks, either way.
@SamuelM333 EnableInterrupt is useful on Arduino Atmega328 boards because you have only 2 pin you can attach interrupt. All the others give you a signal but you have to determine which one. ESP8266 seems different so you can use attachInterrupt to any pin (except 16) in the same way that you use in Arduino for the two dedicated pin. It means that the pin that have interrupted is determined and you don't need this library.
@zoomx Ok could you give me an example of that please?
@SamuelM333 Exactly, I tested this a year ago by using attachInterrupt function in every gpio of esp8266 huzzah feather of adafruit ! @zoomx For further examples and discusses you can find them on this issue https://github.com/esp8266/Arduino/issues/715
I just want to be able to get the pin that got interrupted inside the callback assigned by attachInterrupt
. In all the examples that I've seen, the pins are defined as constants. But I can't do that because I set up the interrupt pins dynamically by a JSON payload. That's why I was interested in Determine the Pin That Was Interrupted.
I don't understand If you don't use attachInterrupt to a pin you don't get any interrupt on that pin. You have to use attachInterrupt on any pin you want to use. You have to use a different interruptHandler for every pin. If in your project you espect an interrupt on 5 pins (for example) you must use attachInterrupt on all 5 pins (five attachInterrupt) and use 5 interruptHandler (interruptHandler is just the name of function called in attachInterrupt.
something like this void HandlerPin1(void){ //something important on pin1 }
void HandlerPin2(void){ //something important on pin2 }
void HandlerPin3(void){ //something important on pin3 }
attachInterrupt(GPIO_1,HandlerPin1,RISING); attachInterrupt(GPIO_2,HandlerPin2,RISING); attachInterrupt(GPIO_3,HandlerPin3,RISING);
There are a tutorial also here https://techtutorialsx.com/2016/12/11/esp8266-external-interrupts/ You don't need to use function digitalPinToInterrupt, you can use directly pin name.
@zoomx Let me show you a piece of my code. Here is a function that receives a JSON object using the ArduinoJSON lib. It setups a port as output and several others as input.
void setup_new_task(JsonObject &task) {
// Set output port pinMode
const char *task_id = task["_id"];
uint8_t output_port_number = task["output_port"]["number"];
pinMode(output_port_number, OUTPUT);
// Set input port pinMode for conditions
JsonArray &conditions = task["conditions"];
for (JsonArray::iterator conditions_iterator = conditions.begin();
conditions_iterator != conditions.end(); ++conditions_iterator) {
if (conditions_iterator->as<JsonObject &>()["input_port"].success()) {
uint8_t input_port_number = conditions_iterator->as<JsonObject &>()["input_port"]["number"];
pinMode(input_port_number, INPUT_PULLUP);
attachInterrupt(input_port_number, general_handler, CHANGE); // This is the functionality that I need
}
}
}
// Somewhere else in my project
void general_handler() {
switch(pin) { // Get pin number somehow
case 1:
//something for pin 1
break;
case 2:
// something for pin 2
break;
// case ...
default :;
}
}
Hope that with this now you understand why I can't have a defined set of handlers. The user can set any valid port as output or input via an API, so I need this dynamic.
This is the project that I'm working on Serverchip/ESP8266. It is a WIP so it's not documented.
You have to add an interruptHandler for every possible pin then you will use only those contained in the json definition file. In every interrupt handle you call general_handler and pass pin number, like in stickbreaker example above. But I believe that is better to break general_handler code and put every case in the interruptHandler for that pin, it's more simple. Remember that if there is not an attachInterrupt for a interruptHandler his code will never be executed.
If you have to change pins you must use detachInterrupt on the previous pins used.
@zoomx I ended up defining a handler for every possible pin like you said. But like @stickbreaker suggested, I defined short functions with a call to a main handler and hardcoding the pin number in each function. I also defined a map to make the things easier. It works and I don't have to check for port changes in each loop(). I still don't like this approach but it's far better than checking all ports every 100ms.
std::map<int, void (*)(void)> input_port_interrupt_handlers;
void pin_state_change(uint8_t pin) {
// Actual hard work for the handler
}
void handler_pin0(void) { pin_state_change(0); }
void handler_pin2(void) { pin_state_change(2); }
void handler_pin3(void) { pin_state_change(3); }
//And so on
input_port_interrupt_handlers[0] = handler_pin0;
input_port_interrupt_handlers[2] = handler_pin2;
input_port_interrupt_handlers[3] = handler_pin3;
// And so on
// Inside setup_new_task(JsonObject &task)
pinMode(input_port_number, INPUT_PULLUP);
detachInterrupt(input_port_number);
attachInterrupt(input_port_number, input_port_interrupt_handlers[input_port_number], CHANGE);
Thanks for all the input and feedback! I'll close this as not an issue.
Is there any chance of integrating esp8266 chips?